Coverage Report

Created: 2022-07-08 09:39

/home/mdboom/Work/builds/cpython/Modules/posixmodule.c
Line
Count
Source (jump to first uncovered line)
1
/* POSIX module implementation */
2
3
/* This file is also used for Windows NT/MS-Win.  In that case the
4
   module actually calls itself 'nt', not 'posix', and a few
5
   functions are either unimplemented or implemented differently.  The source
6
   assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
7
   of the compiler used.  Different compilers define their own feature
8
   test macro, e.g. '_MSC_VER'. */
9
10
#define PY_SSIZE_T_CLEAN
11
12
#include "Python.h"
13
// Include <windows.h> before pycore internal headers. FSCTL_GET_REPARSE_POINT
14
// is not exported by <windows.h> if the WIN32_LEAN_AND_MEAN macro is defined,
15
// whereas pycore_condvar.h defines the WIN32_LEAN_AND_MEAN macro.
16
#ifdef MS_WINDOWS
17
#  include <windows.h>
18
#  include <pathcch.h>
19
#endif
20
21
#ifdef __VXWORKS__
22
#  include "pycore_bitutils.h"    // _Py_popcount32()
23
#endif
24
#include "pycore_call.h"          // _PyObject_CallNoArgs()
25
#include "pycore_ceval.h"         // _PyEval_ReInitThreads()
26
#include "pycore_fileutils.h"     // _Py_closerange()
27
#include "pycore_import.h"        // _PyImport_ReInitLock()
28
#include "pycore_initconfig.h"    // _PyStatus_EXCEPTION()
29
#include "pycore_moduleobject.h"  // _PyModule_GetState()
30
#include "pycore_object.h"        // _PyObject_LookupSpecial()
31
#include "pycore_pystate.h"       // _PyInterpreterState_GET()
32
#include "pycore_signal.h"        // Py_NSIG
33
34
#include "structmember.h"         // PyMemberDef
35
#ifndef MS_WINDOWS
36
#  include "posixmodule.h"
37
#else
38
#  include "winreparse.h"
39
#endif
40
41
#if !defined(EX_OK) && defined(EXIT_SUCCESS)
42
#  define EX_OK EXIT_SUCCESS
43
#endif
44
45
/* On android API level 21, 'AT_EACCESS' is not declared although
46
 * HAVE_FACCESSAT is defined. */
47
#ifdef __ANDROID__
48
#  undef HAVE_FACCESSAT
49
#endif
50
51
#include <stdio.h>                // ctermid()
52
#include <stdlib.h>               // system()
53
54
/*
55
 * A number of APIs are available on macOS from a certain macOS version.
56
 * To support building with a new SDK while deploying to older versions
57
 * the availability test is split into two:
58
 *   - HAVE_<FUNCTION>:  The configure check for compile time availability
59
 *   - HAVE_<FUNCTION>_RUNTIME: Runtime check for availability
60
 *
61
 * The latter is always true when not on macOS, or when using a compiler
62
 * that does not support __has_builtin (older versions of Xcode).
63
 *
64
 * Due to compiler restrictions there is one valid use of HAVE_<FUNCTION>_RUNTIME:
65
 *    if (HAVE_<FUNCTION>_RUNTIME) { ... }
66
 *
67
 * In mixing the test with other tests or using negations will result in compile
68
 * errors.
69
 */
70
#if defined(__APPLE__)
71
72
#if defined(__has_builtin)
73
#if __has_builtin(__builtin_available)
74
#define HAVE_BUILTIN_AVAILABLE 1
75
#endif
76
#endif
77
78
#ifdef HAVE_BUILTIN_AVAILABLE
79
#  define HAVE_FSTATAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
80
#  define HAVE_FACCESSAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
81
#  define HAVE_FCHMODAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
82
#  define HAVE_FCHOWNAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
83
#  define HAVE_LINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
84
#  define HAVE_FDOPENDIR_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
85
#  define HAVE_MKDIRAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
86
#  define HAVE_RENAMEAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
87
#  define HAVE_UNLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
88
#  define HAVE_OPENAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
89
#  define HAVE_READLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
90
#  define HAVE_SYMLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
91
#  define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
92
#  define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
93
#  define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
94
95
#  define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *)
96
97
#else /* Xcode 8 or earlier */
98
99
   /* __builtin_available is not present in these compilers, but
100
    * some of the symbols might be weak linked (10.10 SDK or later
101
    * deploying on 10.9.
102
    *
103
    * Fall back to the older style of availability checking for
104
    * symbols introduced in macOS 10.10.
105
    */
106
107
#  ifdef HAVE_FSTATAT
108
#    define HAVE_FSTATAT_RUNTIME (fstatat != NULL)
109
#  endif
110
111
#  ifdef HAVE_FACCESSAT
112
#    define HAVE_FACCESSAT_RUNTIME (faccessat != NULL)
113
#  endif
114
115
#  ifdef HAVE_FCHMODAT
116
#    define HAVE_FCHMODAT_RUNTIME (fchmodat != NULL)
117
#  endif
118
119
#  ifdef HAVE_FCHOWNAT
120
#    define HAVE_FCHOWNAT_RUNTIME (fchownat != NULL)
121
#  endif
122
123
#  ifdef HAVE_LINKAT
124
#    define HAVE_LINKAT_RUNTIME (linkat != NULL)
125
#  endif
126
127
#  ifdef HAVE_FDOPENDIR
128
#    define HAVE_FDOPENDIR_RUNTIME (fdopendir != NULL)
129
#  endif
130
131
#  ifdef HAVE_MKDIRAT
132
#    define HAVE_MKDIRAT_RUNTIME (mkdirat != NULL)
133
#  endif
134
135
#  ifdef HAVE_RENAMEAT
136
#    define HAVE_RENAMEAT_RUNTIME (renameat != NULL)
137
#  endif
138
139
#  ifdef HAVE_UNLINKAT
140
#    define HAVE_UNLINKAT_RUNTIME (unlinkat != NULL)
141
#  endif
142
143
#  ifdef HAVE_OPENAT
144
#    define HAVE_OPENAT_RUNTIME (openat != NULL)
145
#  endif
146
147
#  ifdef HAVE_READLINKAT
148
#    define HAVE_READLINKAT_RUNTIME (readlinkat != NULL)
149
#  endif
150
151
#  ifdef HAVE_SYMLINKAT
152
#    define HAVE_SYMLINKAT_RUNTIME (symlinkat != NULL)
153
#  endif
154
155
#endif
156
157
#ifdef HAVE_FUTIMESAT
158
/* Some of the logic for weak linking depends on this assertion */
159
# error "HAVE_FUTIMESAT unexpectedly defined"
160
#endif
161
162
#else
163
11.6k
#  define HAVE_FSTATAT_RUNTIME 1
164
5
#  define HAVE_FACCESSAT_RUNTIME 1
165
1
#  define HAVE_FCHMODAT_RUNTIME 1
166
1
#  define HAVE_FCHOWNAT_RUNTIME 1
167
1
#  define HAVE_LINKAT_RUNTIME 1
168
11.7k
#  define HAVE_FDOPENDIR_RUNTIME 1
169
1
#  define HAVE_MKDIRAT_RUNTIME 1
170
1
#  define HAVE_RENAMEAT_RUNTIME 1
171
34.3k
#  define HAVE_UNLINKAT_RUNTIME 1
172
9.61k
#  define HAVE_OPENAT_RUNTIME 1
173
1
#  define HAVE_READLINKAT_RUNTIME 1
174
1
#  define HAVE_SYMLINKAT_RUNTIME 1
175
7
#  define HAVE_FUTIMENS_RUNTIME 1
176
10
#  define HAVE_UTIMENSAT_RUNTIME 1
177
278
#  define HAVE_PWRITEV_RUNTIME 1
178
#endif
179
180
181
#ifdef __cplusplus
182
extern "C" {
183
#endif
184
185
PyDoc_STRVAR(posix__doc__,
186
"This module provides access to operating system functionality that is\n\
187
standardized by the C Standard and the POSIX standard (a thinly\n\
188
disguised Unix interface).  Refer to the library manual and\n\
189
corresponding Unix manual entries for more information on calls.");
190
191
192
#ifdef HAVE_SYS_UIO_H
193
#  include <sys/uio.h>
194
#endif
195
196
#ifdef HAVE_SYS_SYSMACROS_H
197
/* GNU C Library: major(), minor(), makedev() */
198
#  include <sys/sysmacros.h>
199
#endif
200
201
#ifdef HAVE_SYS_TYPES_H
202
#  include <sys/types.h>
203
#endif /* HAVE_SYS_TYPES_H */
204
205
#ifdef HAVE_SYS_STAT_H
206
#  include <sys/stat.h>
207
#endif /* HAVE_SYS_STAT_H */
208
209
#ifdef HAVE_SYS_WAIT_H
210
#  include <sys/wait.h>           // WNOHANG
211
#endif
212
#ifdef HAVE_LINUX_WAIT_H
213
#  include <linux/wait.h>         // P_PIDFD
214
#endif
215
216
#ifdef HAVE_SIGNAL_H
217
#  include <signal.h>
218
#endif
219
220
#ifdef HAVE_FCNTL_H
221
#  include <fcntl.h>
222
#endif
223
224
#ifdef HAVE_GRP_H
225
#  include <grp.h>
226
#endif
227
228
#ifdef HAVE_SYSEXITS_H
229
#  include <sysexits.h>
230
#endif
231
232
#ifdef HAVE_SYS_LOADAVG_H
233
#  include <sys/loadavg.h>
234
#endif
235
236
#ifdef HAVE_SYS_SENDFILE_H
237
#  include <sys/sendfile.h>
238
#endif
239
240
#if defined(__APPLE__)
241
#  include <copyfile.h>
242
#endif
243
244
#ifdef HAVE_SCHED_H
245
#  include <sched.h>
246
#endif
247
248
#ifdef HAVE_COPY_FILE_RANGE
249
#  include <unistd.h>
250
#endif
251
252
#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
253
#  undef HAVE_SCHED_SETAFFINITY
254
#endif
255
256
#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
257
#  define USE_XATTRS
258
#endif
259
260
#ifdef USE_XATTRS
261
#  include <sys/xattr.h>
262
#endif
263
264
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
265
#  ifdef HAVE_SYS_SOCKET_H
266
#    include <sys/socket.h>
267
#  endif
268
#endif
269
270
#ifdef HAVE_DLFCN_H
271
#  include <dlfcn.h>
272
#endif
273
274
#ifdef __hpux
275
#  include <sys/mpctl.h>
276
#endif
277
278
#if defined(__DragonFly__) || \
279
    defined(__OpenBSD__)   || \
280
    defined(__FreeBSD__)   || \
281
    defined(__NetBSD__)    || \
282
    defined(__APPLE__)
283
#  include <sys/sysctl.h>
284
#endif
285
286
#ifdef HAVE_LINUX_RANDOM_H
287
#  include <linux/random.h>
288
#endif
289
#ifdef HAVE_GETRANDOM_SYSCALL
290
#  include <sys/syscall.h>
291
#endif
292
293
#if defined(MS_WINDOWS)
294
#  define TERMSIZE_USE_CONIO
295
#elif defined(HAVE_SYS_IOCTL_H)
296
#  include <sys/ioctl.h>
297
#  if defined(HAVE_TERMIOS_H)
298
#    include <termios.h>
299
#  endif
300
#  if defined(TIOCGWINSZ)
301
#    define TERMSIZE_USE_IOCTL
302
#  endif
303
#endif /* MS_WINDOWS */
304
305
/* Various compilers have only certain posix functions */
306
/* XXX Gosh I wish these were all moved into pyconfig.h */
307
#if defined(__WATCOMC__) && !defined(__QNX__)           /* Watcom compiler */
308
#  define HAVE_OPENDIR    1
309
#  define HAVE_SYSTEM     1
310
#  include <process.h>
311
#else
312
#  ifdef _MSC_VER
313
     /* Microsoft compiler */
314
#    define HAVE_GETPPID    1
315
#    define HAVE_GETLOGIN   1
316
#    define HAVE_SPAWNV     1
317
#    define HAVE_EXECV      1
318
#    define HAVE_WSPAWNV    1
319
#    define HAVE_WEXECV     1
320
#    define HAVE_PIPE       1
321
#    define HAVE_SYSTEM     1
322
#    define HAVE_CWAIT      1
323
#    define HAVE_FSYNC      1
324
#    define fsync _commit
325
#  endif  /* _MSC_VER */
326
#endif  /* ! __WATCOMC__ || __QNX__ */
327
328
/*[clinic input]
329
# one of the few times we lie about this name!
330
module os
331
[clinic start generated code]*/
332
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
333
334
#ifndef _MSC_VER
335
336
#if defined(__sgi)&&_COMPILER_VERSION>=700
337
/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
338
   (default) */
339
extern char        *ctermid_r(char *);
340
#endif
341
342
#endif /* !_MSC_VER */
343
344
#if defined(__VXWORKS__)
345
#  include <vxCpuLib.h>
346
#  include <rtpLib.h>
347
#  include <wait.h>
348
#  include <taskLib.h>
349
#  ifndef _P_WAIT
350
#    define _P_WAIT          0
351
#    define _P_NOWAIT        1
352
#    define _P_NOWAITO       1
353
#  endif
354
#endif /* __VXWORKS__ */
355
356
#ifdef HAVE_POSIX_SPAWN
357
#  include <spawn.h>
358
#endif
359
360
#ifdef HAVE_UTIME_H
361
#  include <utime.h>
362
#endif /* HAVE_UTIME_H */
363
364
#ifdef HAVE_SYS_UTIME_H
365
#  include <sys/utime.h>
366
#  define HAVE_UTIME_H /* pretend we do for the rest of this file */
367
#endif /* HAVE_SYS_UTIME_H */
368
369
#ifdef HAVE_SYS_TIMES_H
370
#  include <sys/times.h>
371
#endif /* HAVE_SYS_TIMES_H */
372
373
#ifdef HAVE_SYS_PARAM_H
374
#  include <sys/param.h>
375
#endif /* HAVE_SYS_PARAM_H */
376
377
#ifdef HAVE_SYS_UTSNAME_H
378
#  include <sys/utsname.h>
379
#endif /* HAVE_SYS_UTSNAME_H */
380
381
#ifdef HAVE_DIRENT_H
382
#  include <dirent.h>
383
478k
#  define NAMLEN(dirent) strlen((dirent)->d_name)
384
#else
385
#  if defined(__WATCOMC__) && !defined(__QNX__)
386
#    include <direct.h>
387
#    define NAMLEN(dirent) strlen((dirent)->d_name)
388
#  else
389
#    define dirent direct
390
#    define NAMLEN(dirent) (dirent)->d_namlen
391
#  endif
392
#  ifdef HAVE_SYS_NDIR_H
393
#    include <sys/ndir.h>
394
#  endif
395
#  ifdef HAVE_SYS_DIR_H
396
#    include <sys/dir.h>
397
#  endif
398
#  ifdef HAVE_NDIR_H
399
#    include <ndir.h>
400
#  endif
401
#endif
402
403
#ifdef _MSC_VER
404
#  ifdef HAVE_DIRECT_H
405
#    include <direct.h>
406
#  endif
407
#  ifdef HAVE_IO_H
408
#    include <io.h>
409
#  endif
410
#  ifdef HAVE_PROCESS_H
411
#    include <process.h>
412
#  endif
413
#  ifndef IO_REPARSE_TAG_SYMLINK
414
#    define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
415
#  endif
416
#  ifndef IO_REPARSE_TAG_MOUNT_POINT
417
#    define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
418
#  endif
419
#  include "osdefs.h"             // SEP
420
#  include <malloc.h>
421
#  include <windows.h>
422
#  include <shellapi.h>           // ShellExecute()
423
#  include <lmcons.h>             // UNLEN
424
#  define HAVE_SYMLINK
425
#endif /* _MSC_VER */
426
427
#ifndef MAXPATHLEN
428
#  if defined(PATH_MAX) && PATH_MAX > 1024
429
#    define MAXPATHLEN PATH_MAX
430
#  else
431
#    define MAXPATHLEN 1024
432
#  endif
433
#endif /* MAXPATHLEN */
434
435
#ifdef UNION_WAIT
436
   /* Emulate some macros on systems that have a union instead of macros */
437
#  ifndef WIFEXITED
438
#    define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
439
#  endif
440
#  ifndef WEXITSTATUS
441
#    define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
442
#  endif
443
#  ifndef WTERMSIG
444
#    define WTERMSIG(u_wait) ((u_wait).w_termsig)
445
#  endif
446
#  define WAIT_TYPE union wait
447
#  define WAIT_STATUS_INT(s) (s.w_status)
448
#else
449
   /* !UNION_WAIT */
450
45.6k
#  define WAIT_TYPE int
451
78.1k
#  define WAIT_STATUS_INT(s) (s)
452
#endif /* UNION_WAIT */
453
454
/* Don't use the "_r" form if we don't need it (also, won't have a
455
   prototype for it, at least on Solaris -- maybe others as well?). */
456
#if defined(HAVE_CTERMID_R)
457
#  define USE_CTERMID_R
458
#endif
459
460
/* choose the appropriate stat and fstat functions and return structs */
461
#undef STAT
462
#undef FSTAT
463
#undef STRUCT_STAT
464
#ifdef MS_WINDOWS
465
#  define STAT win32_stat
466
#  define LSTAT win32_lstat
467
#  define FSTAT _Py_fstat_noraise
468
#  define STRUCT_STAT struct _Py_stat_struct
469
#else
470
346k
#  define STAT stat
471
52.7k
#  define LSTAT lstat
472
30.1k
#  define FSTAT fstat
473
441k
#  define STRUCT_STAT struct stat
474
#endif
475
476
#if defined(MAJOR_IN_MKDEV)
477
#  include <sys/mkdev.h>
478
#else
479
#  if defined(MAJOR_IN_SYSMACROS)
480
#    include <sys/sysmacros.h>
481
#  endif
482
#  if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
483
#    include <sys/mkdev.h>
484
#  endif
485
#endif
486
487
#ifdef MS_WINDOWS
488
#  define INITFUNC PyInit_nt
489
#  define MODNAME "nt"
490
#else
491
#  define INITFUNC PyInit_posix
492
834
#  define MODNAME "posix"
493
#endif
494
495
#if defined(__sun)
496
/* Something to implement in autoconf, not present in autoconf 2.69 */
497
#  define HAVE_STRUCT_STAT_ST_FSTYPE 1
498
#endif
499
500
/* memfd_create is either defined in sys/mman.h or sys/memfd.h
501
 * linux/memfd.h defines additional flags
502
 */
503
#ifdef HAVE_SYS_MMAN_H
504
#  include <sys/mman.h>
505
#endif
506
#ifdef HAVE_SYS_MEMFD_H
507
#  include <sys/memfd.h>
508
#endif
509
#ifdef HAVE_LINUX_MEMFD_H
510
#  include <linux/memfd.h>
511
#endif
512
513
/* eventfd() */
514
#ifdef HAVE_SYS_EVENTFD_H
515
#  include <sys/eventfd.h>
516
#endif
517
518
#ifdef _Py_MEMORY_SANITIZER
519
#  include <sanitizer/msan_interface.h>
520
#endif
521
522
#ifdef HAVE_FORK
523
static void
524
run_at_forkers(PyObject *lst, int reverse)
525
1.82k
{
526
1.82k
    Py_ssize_t i;
527
1.82k
    PyObject *cpy;
528
529
1.82k
    if (lst != NULL) {
  Branch (529:9): [True: 1.82k, False: 0]
530
1.82k
        assert(PyList_CheckExact(lst));
531
532
        /* Use a list copy in case register_at_fork() is called from
533
         * one of the callbacks.
534
         */
535
1.82k
        cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
Line
Count
Source
37
1.82k
#define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op))
Line
Count
Source
109
1.82k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1.82k
#  define _Py_CAST(type, expr) ((type)(expr))
536
1.82k
        if (cpy == NULL)
  Branch (536:13): [True: 0, False: 1.82k]
537
0
            PyErr_WriteUnraisable(lst);
538
1.82k
        else {
539
1.82k
            if (reverse)
  Branch (539:17): [True: 911, False: 911]
540
911
                PyList_Reverse(cpy);
541
5.45k
            for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
Line
Count
Source
37
5.45k
#define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op))
Line
Count
Source
109
5.45k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5.45k
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (541:25): [True: 3.63k, False: 1.82k]
542
3.63k
                PyObject *func, *res;
543
3.63k
                func = PyList_GET_ITEM(cpy, i);
Line
Count
Source
39
3.63k
#define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[(index)])
Line
Count
Source
29
3.63k
    (assert(PyList_Check(op)), _Py_CAST(PyListObject*, (op)))
Line
Count
Source
71
3.63k
#  define _Py_CAST(type, expr) ((type)(expr))
544
3.63k
                res = _PyObject_CallNoArgs(func);
545
3.63k
                if (res == NULL)
  Branch (545:21): [True: 0, False: 3.63k]
546
0
                    PyErr_WriteUnraisable(func);
547
3.63k
                else
548
3.63k
                    Py_DECREF(res);
Line
Count
Source
548
3.63k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
3.63k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
3.63k
#  define _Py_CAST(type, expr) ((type)(expr))
549
3.63k
            }
550
1.82k
            Py_DECREF(cpy);
Line
Count
Source
548
1.82k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
1.82k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1.82k
#  define _Py_CAST(type, expr) ((type)(expr))
551
1.82k
        }
552
1.82k
    }
553
1.82k
}
554
555
void
556
PyOS_BeforeFork(void)
557
911
{
558
911
    run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1);
559
560
911
    _PyImport_AcquireLock();
561
911
}
562
563
void
564
PyOS_AfterFork_Parent(void)
565
911
{
566
911
    if (_PyImport_ReleaseLock() <= 0)
  Branch (566:9): [True: 0, False: 911]
567
0
        Py_FatalError("failed releasing import lock after fork");
Line
Count
Source
179
0
#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, (message))
568
569
911
    run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0);
570
911
}
571
572
void
573
PyOS_AfterFork_Child(void)
574
0
{
575
0
    PyStatus status;
576
0
    _PyRuntimeState *runtime = &_PyRuntime;
577
578
0
    status = _PyGILState_Reinit(runtime);
579
0
    if (_PyStatus_EXCEPTION(status)) {
Line
Count
Source
43
0
    ((err)._type != _PyStatus_TYPE_OK)
  Branch (43:5): [True: 0, False: 0]
580
0
        goto fatal_error;
581
0
    }
582
583
0
    PyThreadState *tstate = _PyThreadState_GET();
584
0
    _Py_EnsureTstateNotNULL(tstate);
Line
Count
Source
100
0
    _Py_EnsureFuncTstateNotNULL(__func__, (tstate))
585
586
0
    status = _PyEval_ReInitThreads(tstate);
587
0
    if (_PyStatus_EXCEPTION(status)) {
Line
Count
Source
43
0
    ((err)._type != _PyStatus_TYPE_OK)
  Branch (43:5): [True: 0, False: 0]
588
0
        goto fatal_error;
589
0
    }
590
591
0
    status = _PyImport_ReInitLock();
592
0
    if (_PyStatus_EXCEPTION(status)) {
Line
Count
Source
43
0
    ((err)._type != _PyStatus_TYPE_OK)
  Branch (43:5): [True: 0, False: 0]
593
0
        goto fatal_error;
594
0
    }
595
596
0
    _PySignal_AfterFork();
597
598
0
    status = _PyRuntimeState_ReInitThreads(runtime);
599
0
    if (_PyStatus_EXCEPTION(status)) {
Line
Count
Source
43
0
    ((err)._type != _PyStatus_TYPE_OK)
  Branch (43:5): [True: 0, False: 0]
600
0
        goto fatal_error;
601
0
    }
602
603
0
    status = _PyInterpreterState_DeleteExceptMain(runtime);
604
0
    if (_PyStatus_EXCEPTION(status)) {
Line
Count
Source
43
0
    ((err)._type != _PyStatus_TYPE_OK)
  Branch (43:5): [True: 0, False: 0]
605
0
        goto fatal_error;
606
0
    }
607
0
    assert(_PyThreadState_GET() == tstate);
608
609
0
    run_at_forkers(tstate->interp->after_forkers_child, 0);
610
0
    return;
611
612
0
fatal_error:
613
0
    Py_ExitStatusException(status);
614
0
}
615
616
static int
617
register_at_forker(PyObject **lst, PyObject *func)
618
27
{
619
27
    if (func == NULL)  /* nothing to register? do nothing. */
  Branch (619:9): [True: 14, False: 13]
620
14
        return 0;
621
13
    if (*lst == NULL) {
  Branch (621:9): [True: 6, False: 7]
622
6
        *lst = PyList_New(0);
623
6
        if (*lst == NULL)
  Branch (623:13): [True: 0, False: 6]
624
0
            return -1;
625
6
    }
626
13
    return PyList_Append(*lst, func);
627
13
}
628
#endif  /* HAVE_FORK */
629
630
631
/* Legacy wrapper */
632
void
633
PyOS_AfterFork(void)
634
0
{
635
0
#ifdef HAVE_FORK
636
0
    PyOS_AfterFork_Child();
637
0
#endif
638
0
}
639
640
641
#ifdef MS_WINDOWS
642
/* defined in fileutils.c */
643
void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
644
void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
645
                                            ULONG, struct _Py_stat_struct *);
646
#endif
647
648
649
#ifndef MS_WINDOWS
650
PyObject *
651
_PyLong_FromUid(uid_t uid)
652
328k
{
653
328k
    if (uid == (uid_t)-1)
  Branch (653:9): [True: 1, False: 328k]
654
1
        return PyLong_FromLong(-1);
655
328k
    return PyLong_FromUnsignedLong(uid);
656
328k
}
657
658
PyObject *
659
_PyLong_FromGid(gid_t gid)
660
328k
{
661
328k
    if (gid == (gid_t)-1)
  Branch (661:9): [True: 0, False: 328k]
662
0
        return PyLong_FromLong(-1);
663
328k
    return PyLong_FromUnsignedLong(gid);
664
328k
}
665
666
int
667
_Py_Uid_Converter(PyObject *obj, uid_t *p)
668
687
{
669
687
    uid_t uid;
670
687
    PyObject *index;
671
687
    int overflow;
672
687
    long result;
673
687
    unsigned long uresult;
674
675
687
    index = _PyNumber_Index(obj);
676
687
    if (index == NULL) {
  Branch (676:9): [True: 16, False: 671]
677
16
        PyErr_Format(PyExc_TypeError,
678
16
                     "uid should be integer, not %.200s",
679
16
                     _PyType_Name(Py_TYPE(obj)));
Line
Count
Source
138
16
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
16
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
16
#  define _Py_CAST(type, expr) ((type)(expr))
680
16
        return 0;
681
16
    }
682
683
    /*
684
     * Handling uid_t is complicated for two reasons:
685
     *  * Although uid_t is (always?) unsigned, it still
686
     *    accepts -1.
687
     *  * We don't know its size in advance--it may be
688
     *    bigger than an int, or it may be smaller than
689
     *    a long.
690
     *
691
     * So a bit of defensive programming is in order.
692
     * Start with interpreting the value passed
693
     * in as a signed long and see if it works.
694
     */
695
696
671
    result = PyLong_AsLongAndOverflow(index, &overflow);
697
698
671
    if (!overflow) {
  Branch (698:9): [True: 668, False: 3]
699
668
        uid = (uid_t)result;
700
701
668
        if (result == -1) {
  Branch (701:13): [True: 17, False: 651]
702
17
            if (PyErr_Occurred())
  Branch (702:17): [True: 0, False: 17]
703
0
                goto fail;
704
            /* It's a legitimate -1, we're done. */
705
17
            goto success;
706
17
        }
707
708
        /* Any other negative number is disallowed. */
709
651
        if (result < 0)
  Branch (709:13): [True: 0, False: 651]
710
0
            goto underflow;
711
712
        /* Ensure the value wasn't truncated. */
713
651
        if (sizeof(uid_t) < sizeof(long) &&
  Branch (713:13): [Folded - Ignored]
714
651
            (long)uid != result)
  Branch (714:13): [True: 5, False: 646]
715
5
            goto underflow;
716
646
        goto success;
717
651
    }
718
719
3
    if (overflow < 0)
  Branch (719:9): [True: 1, False: 2]
720
1
        goto underflow;
721
722
    /*
723
     * Okay, the value overflowed a signed long.  If it
724
     * fits in an *unsigned* long, it may still be okay,
725
     * as uid_t may be unsigned long on this platform.
726
     */
727
2
    uresult = PyLong_AsUnsignedLong(index);
728
2
    if (PyErr_Occurred()) {
  Branch (728:9): [True: 2, False: 0]
729
2
        if (PyErr_ExceptionMatches(PyExc_OverflowError))
  Branch (729:13): [True: 2, False: 0]
730
2
            goto overflow;
731
0
        goto fail;
732
2
    }
733
734
0
    uid = (uid_t)uresult;
735
736
    /*
737
     * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
738
     * but this value would get interpreted as (uid_t)-1  by chown
739
     * and its siblings.   That's not what the user meant!  So we
740
     * throw an overflow exception instead.   (We already
741
     * handled a real -1 with PyLong_AsLongAndOverflow() above.)
742
     */
743
0
    if (uid == (uid_t)-1)
  Branch (743:9): [True: 0, False: 0]
744
0
        goto overflow;
745
746
    /* Ensure the value wasn't truncated. */
747
0
    if (sizeof(uid_t) < sizeof(long) &&
  Branch (747:9): [Folded - Ignored]
748
0
        (unsigned long)uid != uresult)
  Branch (748:9): [True: 0, False: 0]
749
0
        goto overflow;
750
    /* fallthrough */
751
752
663
success:
753
663
    Py_DECREF(index);
Line
Count
Source
548
663
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
663
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
663
#  define _Py_CAST(type, expr) ((type)(expr))
754
663
    *p = uid;
755
663
    return 1;
756
757
6
underflow:
758
6
    PyErr_SetString(PyExc_OverflowError,
759
6
                    "uid is less than minimum");
760
6
    goto fail;
761
762
2
overflow:
763
2
    PyErr_SetString(PyExc_OverflowError,
764
2
                    "uid is greater than maximum");
765
    /* fallthrough */
766
767
8
fail:
768
8
    Py_DECREF(index);
Line
Count
Source
548
8
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
8
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8
#  define _Py_CAST(type, expr) ((type)(expr))
769
8
    return 0;
770
2
}
771
772
int
773
_Py_Gid_Converter(PyObject *obj, gid_t *p)
774
694
{
775
694
    gid_t gid;
776
694
    PyObject *index;
777
694
    int overflow;
778
694
    long result;
779
694
    unsigned long uresult;
780
781
694
    index = _PyNumber_Index(obj);
782
694
    if (index == NULL) {
  Branch (782:9): [True: 17, False: 677]
783
17
        PyErr_Format(PyExc_TypeError,
784
17
                     "gid should be integer, not %.200s",
785
17
                     _PyType_Name(Py_TYPE(obj)));
Line
Count
Source
138
17
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
17
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
17
#  define _Py_CAST(type, expr) ((type)(expr))
786
17
        return 0;
787
17
    }
788
789
    /*
790
     * Handling gid_t is complicated for two reasons:
791
     *  * Although gid_t is (always?) unsigned, it still
792
     *    accepts -1.
793
     *  * We don't know its size in advance--it may be
794
     *    bigger than an int, or it may be smaller than
795
     *    a long.
796
     *
797
     * So a bit of defensive programming is in order.
798
     * Start with interpreting the value passed
799
     * in as a signed long and see if it works.
800
     */
801
802
677
    result = PyLong_AsLongAndOverflow(index, &overflow);
803
804
677
    if (!overflow) {
  Branch (804:9): [True: 675, False: 2]
805
675
        gid = (gid_t)result;
806
807
675
        if (result == -1) {
  Branch (807:13): [True: 18, False: 657]
808
18
            if (PyErr_Occurred())
  Branch (808:17): [True: 0, False: 18]
809
0
                goto fail;
810
            /* It's a legitimate -1, we're done. */
811
18
            goto success;
812
18
        }
813
814
        /* Any other negative number is disallowed. */
815
657
        if (result < 0) {
  Branch (815:13): [True: 0, False: 657]
816
0
            goto underflow;
817
0
        }
818
819
        /* Ensure the value wasn't truncated. */
820
657
        if (sizeof(gid_t) < sizeof(long) &&
  Branch (820:13): [Folded - Ignored]
821
657
            (long)gid != result)
  Branch (821:13): [True: 4, False: 653]
822
4
            goto underflow;
823
653
        goto success;
824
657
    }
825
826
2
    if (overflow < 0)
  Branch (826:9): [True: 0, False: 2]
827
0
        goto underflow;
828
829
    /*
830
     * Okay, the value overflowed a signed long.  If it
831
     * fits in an *unsigned* long, it may still be okay,
832
     * as gid_t may be unsigned long on this platform.
833
     */
834
2
    uresult = PyLong_AsUnsignedLong(index);
835
2
    if (PyErr_Occurred()) {
  Branch (835:9): [True: 2, False: 0]
836
2
        if (PyErr_ExceptionMatches(PyExc_OverflowError))
  Branch (836:13): [True: 2, False: 0]
837
2
            goto overflow;
838
0
        goto fail;
839
2
    }
840
841
0
    gid = (gid_t)uresult;
842
843
    /*
844
     * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
845
     * but this value would get interpreted as (gid_t)-1  by chown
846
     * and its siblings.   That's not what the user meant!  So we
847
     * throw an overflow exception instead.   (We already
848
     * handled a real -1 with PyLong_AsLongAndOverflow() above.)
849
     */
850
0
    if (gid == (gid_t)-1)
  Branch (850:9): [True: 0, False: 0]
851
0
        goto overflow;
852
853
    /* Ensure the value wasn't truncated. */
854
0
    if (sizeof(gid_t) < sizeof(long) &&
  Branch (854:9): [Folded - Ignored]
855
0
        (unsigned long)gid != uresult)
  Branch (855:9): [True: 0, False: 0]
856
0
        goto overflow;
857
    /* fallthrough */
858
859
671
success:
860
671
    Py_DECREF(index);
Line
Count
Source
548
671
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
671
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
671
#  define _Py_CAST(type, expr) ((type)(expr))
861
671
    *p = gid;
862
671
    return 1;
863
864
4
underflow:
865
4
    PyErr_SetString(PyExc_OverflowError,
866
4
                    "gid is less than minimum");
867
4
    goto fail;
868
869
2
overflow:
870
2
    PyErr_SetString(PyExc_OverflowError,
871
2
                    "gid is greater than maximum");
872
    /* fallthrough */
873
874
6
fail:
875
6
    Py_DECREF(index);
Line
Count
Source
548
6
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
6
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
6
#  define _Py_CAST(type, expr) ((type)(expr))
876
6
    return 0;
877
2
}
878
#endif /* MS_WINDOWS */
879
880
881
1
#define _PyLong_FromDev PyLong_FromLongLong
882
883
884
#if (defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)) || defined(HAVE_DEVICE_MACROS)
885
static int
886
_Py_Dev_Converter(PyObject *obj, void *p)
887
11
{
888
11
    *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
889
11
    if (PyErr_Occurred())
  Branch (889:9): [True: 4, False: 7]
890
4
        return 0;
891
7
    return 1;
892
11
}
893
#endif /* (HAVE_MKNOD && HAVE_MAKEDEV) || HAVE_DEVICE_MACROS */
894
895
896
#ifdef AT_FDCWD
897
/*
898
 * Why the (int) cast?  Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
899
 * without the int cast, the value gets interpreted as uint (4291925331),
900
 * which doesn't play nicely with all the initializer lines in this file that
901
 * look like this:
902
 *      int dir_fd = DEFAULT_DIR_FD;
903
 */
904
2.02M
#define DEFAULT_DIR_FD (int)AT_FDCWD
905
#else
906
#define DEFAULT_DIR_FD (-100)
907
#endif
908
909
static int
910
_fd_converter(PyObject *o, int *p)
911
63.5k
{
912
63.5k
    int overflow;
913
63.5k
    long long_value;
914
915
63.5k
    PyObject *index = _PyNumber_Index(o);
916
63.5k
    if (index == NULL) {
  Branch (916:9): [True: 0, False: 63.5k]
917
0
        return 0;
918
0
    }
919
920
63.5k
    assert(PyLong_Check(index));
921
63.5k
    long_value = PyLong_AsLongAndOverflow(index, &overflow);
922
63.5k
    Py_DECREF(index);
Line
Count
Source
548
63.5k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
63.5k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
63.5k
#  define _Py_CAST(type, expr) ((type)(expr))
923
63.5k
    assert(!PyErr_Occurred());
924
63.5k
    if (overflow > 0 || long_value > INT_MAX) {
  Branch (924:9): [True: 1, False: 63.5k]
  Branch (924:25): [True: 0, False: 63.5k]
925
1
        PyErr_SetString(PyExc_OverflowError,
926
1
                        "fd is greater than maximum");
927
1
        return 0;
928
1
    }
929
63.5k
    if (overflow < 0 || long_value < INT_MIN) {
  Branch (929:9): [True: 0, False: 63.5k]
  Branch (929:25): [True: 0, False: 63.5k]
930
0
        PyErr_SetString(PyExc_OverflowError,
931
0
                        "fd is less than minimum");
932
0
        return 0;
933
0
    }
934
935
63.5k
    *p = (int)long_value;
936
63.5k
    return 1;
937
63.5k
}
938
939
static int
940
dir_fd_converter(PyObject *o, void *p)
941
57.5k
{
942
57.5k
    if (o == Py_None) {
Line
Count
Source
654
57.5k
#define Py_None (&_Py_NoneStruct)
  Branch (942:9): [True: 9.77k, False: 47.8k]
943
9.77k
        *(int *)p = DEFAULT_DIR_FD;
Line
Count
Source
904
9.77k
#define DEFAULT_DIR_FD (int)AT_FDCWD
944
9.77k
        return 1;
945
9.77k
    }
946
47.8k
    else if (PyIndex_Check(o)) {
  Branch (946:14): [True: 47.8k, False: 2]
947
47.8k
        return _fd_converter(o, (int *)p);
948
47.8k
    }
949
2
    else {
950
2
        PyErr_Format(PyExc_TypeError,
951
2
                     "argument should be integer or None, not %.200s",
952
2
                     _PyType_Name(Py_TYPE(o)));
Line
Count
Source
138
2
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
953
2
        return 0;
954
2
    }
955
57.5k
}
956
957
typedef struct {
958
    PyObject *billion;
959
    PyObject *DirEntryType;
960
    PyObject *ScandirIteratorType;
961
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
962
    PyObject *SchedParamType;
963
#endif
964
    PyObject *StatResultType;
965
    PyObject *StatVFSResultType;
966
    PyObject *TerminalSizeType;
967
    PyObject *TimesResultType;
968
    PyObject *UnameResultType;
969
#if defined(HAVE_WAITID) && !defined(__APPLE__)
970
    PyObject *WaitidResultType;
971
#endif
972
#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
973
    PyObject *struct_rusage;
974
#endif
975
    PyObject *st_mode;
976
} _posixstate;
977
978
979
static inline _posixstate*
980
get_posix_state(PyObject *module)
981
1.51M
{
982
1.51M
    void *state = _PyModule_GetState(module);
983
1.51M
    assert(state != NULL);
984
1.51M
    return (_posixstate *)state;
985
1.51M
}
986
987
/*
988
 * A PyArg_ParseTuple "converter" function
989
 * that handles filesystem paths in the manner
990
 * preferred by the os module.
991
 *
992
 * path_converter accepts (Unicode) strings and their
993
 * subclasses, and bytes and their subclasses.  What
994
 * it does with the argument depends on the platform:
995
 *
996
 *   * On Windows, if we get a (Unicode) string we
997
 *     extract the wchar_t * and return it; if we get
998
 *     bytes we decode to wchar_t * and return that.
999
 *
1000
 *   * On all other platforms, strings are encoded
1001
 *     to bytes using PyUnicode_FSConverter, then we
1002
 *     extract the char * from the bytes object and
1003
 *     return that.
1004
 *
1005
 * path_converter also optionally accepts signed
1006
 * integers (representing open file descriptors) instead
1007
 * of path strings.
1008
 *
1009
 * Input fields:
1010
 *   path.nullable
1011
 *     If nonzero, the path is permitted to be None.
1012
 *   path.allow_fd
1013
 *     If nonzero, the path is permitted to be a file handle
1014
 *     (a signed int) instead of a string.
1015
 *   path.function_name
1016
 *     If non-NULL, path_converter will use that as the name
1017
 *     of the function in error messages.
1018
 *     (If path.function_name is NULL it omits the function name.)
1019
 *   path.argument_name
1020
 *     If non-NULL, path_converter will use that as the name
1021
 *     of the parameter in error messages.
1022
 *     (If path.argument_name is NULL it uses "path".)
1023
 *
1024
 * Output fields:
1025
 *   path.wide
1026
 *     Points to the path if it was expressed as Unicode
1027
 *     and was not encoded.  (Only used on Windows.)
1028
 *   path.narrow
1029
 *     Points to the path if it was expressed as bytes,
1030
 *     or it was Unicode and was encoded to bytes. (On Windows,
1031
 *     is a non-zero integer if the path was expressed as bytes.
1032
 *     The type is deliberately incompatible to prevent misuse.)
1033
 *   path.fd
1034
 *     Contains a file descriptor if path.accept_fd was true
1035
 *     and the caller provided a signed integer instead of any
1036
 *     sort of string.
1037
 *
1038
 *     WARNING: if your "path" parameter is optional, and is
1039
 *     unspecified, path_converter will never get called.
1040
 *     So if you set allow_fd, you *MUST* initialize path.fd = -1
1041
 *     yourself!
1042
 *   path.length
1043
 *     The length of the path in characters, if specified as
1044
 *     a string.
1045
 *   path.object
1046
 *     The original object passed in (if get a PathLike object,
1047
 *     the result of PyOS_FSPath() is treated as the original object).
1048
 *     Own a reference to the object.
1049
 *   path.cleanup
1050
 *     For internal use only.  May point to a temporary object.
1051
 *     (Pay no attention to the man behind the curtain.)
1052
 *
1053
 *   At most one of path.wide or path.narrow will be non-NULL.
1054
 *   If path was None and path.nullable was set,
1055
 *     or if path was an integer and path.allow_fd was set,
1056
 *     both path.wide and path.narrow will be NULL
1057
 *     and path.length will be 0.
1058
 *
1059
 *   path_converter takes care to not write to the path_t
1060
 *   unless it's successful.  However it must reset the
1061
 *   "cleanup" field each time it's called.
1062
 *
1063
 * Use as follows:
1064
 *      path_t path;
1065
 *      memset(&path, 0, sizeof(path));
1066
 *      PyArg_ParseTuple(args, "O&", path_converter, &path);
1067
 *      // ... use values from path ...
1068
 *      path_cleanup(&path);
1069
 *
1070
 * (Note that if PyArg_Parse fails you don't need to call
1071
 * path_cleanup().  However it is safe to do so.)
1072
 */
1073
typedef struct {
1074
    const char *function_name;
1075
    const char *argument_name;
1076
    int nullable;
1077
    int allow_fd;
1078
    const wchar_t *wide;
1079
#ifdef MS_WINDOWS
1080
    BOOL narrow;
1081
#else
1082
    const char *narrow;
1083
#endif
1084
    int fd;
1085
    Py_ssize_t length;
1086
    PyObject *object;
1087
    PyObject *cleanup;
1088
} path_t;
1089
1090
#ifdef MS_WINDOWS
1091
#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1092
    {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
1093
#else
1094
#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1095
576k
    {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
1096
#endif
1097
1098
static void
1099
path_cleanup(path_t *path)
1100
622k
{
1101
622k
    wchar_t *wide = (wchar_t *)path->wide;
1102
622k
    path->wide = NULL;
1103
622k
    PyMem_Free(wide);
1104
622k
    Py_CLEAR(path->object);
Line
Count
Source
587
622k
    do {                                        \
588
622k
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
622k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
622k
#  define _Py_CAST(type, expr) ((type)(expr))
589
622k
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 574k, False: 48.0k]
590
574k
            (op) = NULL;                        \
591
574k
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
574k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
574k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
574k
#  define _Py_CAST(type, expr) ((type)(expr))
592
574k
        }                                       \
593
622k
    } while (0)
  Branch (593:14): [Folded - Ignored]
1105
622k
    Py_CLEAR(path->cleanup);
Line
Count
Source
587
622k
    do {                                        \
588
622k
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
622k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
622k
#  define _Py_CAST(type, expr) ((type)(expr))
589
622k
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 540k, False: 82.0k]
590
540k
            (op) = NULL;                        \
591
540k
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
540k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
540k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
540k
#  define _Py_CAST(type, expr) ((type)(expr))
592
540k
        }                                       \
593
622k
    } while (0)
  Branch (593:14): [Folded - Ignored]
1106
622k
}
1107
1108
static int
1109
path_converter(PyObject *o, void *p)
1110
575k
{
1111
575k
    path_t *path = (path_t *)p;
1112
575k
    PyObject *bytes = NULL;
1113
575k
    Py_ssize_t length = 0;
1114
575k
    int is_index, is_buffer, is_bytes, is_unicode;
1115
575k
    const char *narrow;
1116
#ifdef MS_WINDOWS
1117
    PyObject *wo = NULL;
1118
    wchar_t *wide = NULL;
1119
#endif
1120
1121
575k
#define FORMAT_EXCEPTION(exc, fmt) \
1122
575k
    PyErr_Format(exc, "%s%s" fmt, \
1123
25
        path->function_name ? path->function_name : "", \
1124
25
        path->function_name ? ": "                : "", \
1125
25
        path->argument_name ? path->argument_name : "path")
1126
1127
    /* Py_CLEANUP_SUPPORTED support */
1128
575k
    if (o == NULL) {
  Branch (1128:9): [True: 0, False: 575k]
1129
0
        path_cleanup(path);
1130
0
        return 1;
1131
0
    }
1132
1133
    /* Ensure it's always safe to call path_cleanup(). */
1134
575k
    path->object = path->cleanup = NULL;
1135
    /* path->object owns a reference to the original object */
1136
575k
    Py_INCREF(o);
Line
Count
Source
512
575k
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
575k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
575k
#  define _Py_CAST(type, expr) ((type)(expr))
1137
1138
575k
    if ((o == Py_None) && path->nullable) {
Line
Count
Source
654
575k
#define Py_None (&_Py_NoneStruct)
  Branch (1138:9): [True: 1, False: 575k]
  Branch (1138:27): [True: 0, False: 1]
1139
0
        path->wide = NULL;
1140
#ifdef MS_WINDOWS
1141
        path->narrow = FALSE;
1142
#else
1143
0
        path->narrow = NULL;
1144
0
#endif
1145
0
        path->fd = -1;
1146
0
        goto success_exit;
1147
0
    }
1148
1149
    /* Only call this here so that we don't treat the return value of
1150
       os.fspath() as an fd or buffer. */
1151
575k
    is_index = path->allow_fd && PyIndex_Check(o);
  Branch (1151:16): [True: 437k, False: 137k]
  Branch (1151:34): [True: 15.7k, False: 421k]
1152
575k
    is_buffer = PyObject_CheckBuffer(o);
1153
575k
    is_bytes = PyBytes_Check(o);
Line
Count
Source
31
575k
                 PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS)
Line
Count
Source
782
575k
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
1154
575k
    is_unicode = PyUnicode_Check(o);
Line
Count
Source
115
575k
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
Line
Count
Source
782
575k
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
1155
1156
575k
    if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
  Branch (1156:9): [True: 559k, False: 15.7k]
  Branch (1156:22): [True: 540k, False: 18.2k]
  Branch (1156:36): [True: 30.3k, False: 510k]
  Branch (1156:51): [True: 30.3k, False: 0]
1157
        /* Inline PyOS_FSPath() for better error messages. */
1158
30.3k
        PyObject *func, *res;
1159
1160
30.3k
        func = _PyObject_LookupSpecial(o, &_Py_ID(__fspath__));
Line
Count
Source
374
30.3k
     (_Py_SINGLETON(strings.identifiers._ ## NAME._ascii.ob_base))
Line
Count
Source
26
30.3k
    _Py_GLOBAL_OBJECT(singletons.NAME)
Line
Count
Source
24
30.3k
    _PyRuntime.global_objects.NAME
1161
30.3k
        if (NULL == func) {
  Branch (1161:13): [True: 12, False: 30.3k]
1162
12
            goto error_format;
1163
12
        }
1164
30.3k
        res = _PyObject_CallNoArgs(func);
1165
30.3k
        Py_DECREF(func);
Line
Count
Source
548
30.3k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
30.3k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
30.3k
#  define _Py_CAST(type, expr) ((type)(expr))
1166
30.3k
        if (NULL == res) {
  Branch (1166:13): [True: 0, False: 30.3k]
1167
0
            goto error_exit;
1168
0
        }
1169
30.3k
        else if (PyUnicode_Check(res)) {
Line
Count
Source
115
30.3k
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
Line
Count
Source
782
30.3k
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (782:41): [True: 30.2k, False: 12]
1170
30.2k
            is_unicode = 1;
1171
30.2k
        }
1172
12
        else if (PyBytes_Check(res)) {
Line
Count
Source
31
12
                 PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS)
Line
Count
Source
782
12
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (782:41): [True: 5, False: 7]
1173
5
            is_bytes = 1;
1174
5
        }
1175
7
        else {
1176
7
            PyErr_Format(PyExc_TypeError,
1177
7
                 "expected %.200s.__fspath__() to return str or bytes, "
1178
7
                 "not %.200s", _PyType_Name(Py_TYPE(o)),
Line
Count
Source
138
7
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
7
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7
#  define _Py_CAST(type, expr) ((type)(expr))
1179
7
                 _PyType_Name(Py_TYPE(res)));
Line
Count
Source
138
7
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
7
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7
#  define _Py_CAST(type, expr) ((type)(expr))
1180
7
            Py_DECREF(res);
Line
Count
Source
548
7
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
7
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7
#  define _Py_CAST(type, expr) ((type)(expr))
1181
7
            goto error_exit;
1182
7
        }
1183
1184
        /* still owns a reference to the original object */
1185
30.2k
        Py_DECREF(o);
Line
Count
Source
548
30.2k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
30.2k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
30.2k
#  define _Py_CAST(type, expr) ((type)(expr))
1186
30.2k
        o = res;
1187
30.2k
    }
1188
1189
574k
    if (is_unicode) {
  Branch (1189:9): [True: 540k, False: 34.0k]
1190
#ifdef MS_WINDOWS
1191
        wide = PyUnicode_AsWideCharString(o, &length);
1192
        if (!wide) {
1193
            goto error_exit;
1194
        }
1195
        if (length > 32767) {
1196
            FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
1197
            goto error_exit;
1198
        }
1199
        if (wcslen(wide) != length) {
1200
            FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
1201
            goto error_exit;
1202
        }
1203
1204
        path->wide = wide;
1205
        path->narrow = FALSE;
1206
        path->fd = -1;
1207
        wide = NULL;
1208
        goto success_exit;
1209
#else
1210
540k
        if (!PyUnicode_FSConverter(o, &bytes)) {
  Branch (1210:13): [True: 106, False: 540k]
1211
106
            goto error_exit;
1212
106
        }
1213
540k
#endif
1214
540k
    }
1215
34.0k
    else if (is_bytes) {
  Branch (1215:14): [True: 18.2k, False: 15.7k]
1216
18.2k
        bytes = o;
1217
18.2k
        Py_INCREF(bytes);
Line
Count
Source
512
18.2k
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
18.2k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
18.2k
#  define _Py_CAST(type, expr) ((type)(expr))
1218
18.2k
    }
1219
15.7k
    else if (is_buffer) {
  Branch (1219:14): [True: 45, False: 15.7k]
1220
        /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
1221
           after removing support of non-bytes buffer objects. */
1222
45
        if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
  Branch (1222:13): [True: 0, False: 45]
1223
45
            "%s%s%s should be %s, not %.200s",
1224
45
            path->function_name ? path->function_name : "",
  Branch (1224:13): [True: 45, False: 0]
1225
45
            path->function_name ? ": "                : "",
  Branch (1225:13): [True: 45, False: 0]
1226
45
            path->argument_name ? path->argument_name : "path",
  Branch (1226:13): [True: 45, False: 0]
1227
45
            path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
  Branch (1227:13): [True: 25, False: 20]
  Branch (1227:31): [True: 8, False: 17]
1228
8
                                               "integer or None" :
1229
45
            path->allow_fd ? "string, bytes, os.PathLike or integer" :
  Branch (1229:13): [True: 17, False: 20]
1230
37
            path->nullable ? "string, bytes, os.PathLike or None" :
  Branch (1230:13): [True: 0, False: 20]
1231
20
                             "string, bytes or os.PathLike",
1232
45
            _PyType_Name(Py_TYPE(o)))) {
Line
Count
Source
138
45
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
45
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
45
#  define _Py_CAST(type, expr) ((type)(expr))
1233
0
            goto error_exit;
1234
0
        }
1235
45
        bytes = PyBytes_FromObject(o);
1236
45
        if (!bytes) {
  Branch (1236:13): [True: 0, False: 45]
1237
0
            goto error_exit;
1238
0
        }
1239
45
    }
1240
15.7k
    else if (is_index) {
  Branch (1240:14): [True: 15.7k, False: 0]
1241
15.7k
        if (!_fd_converter(o, &path->fd)) {
  Branch (1241:13): [True: 0, False: 15.7k]
1242
0
            goto error_exit;
1243
0
        }
1244
15.7k
        path->wide = NULL;
1245
#ifdef MS_WINDOWS
1246
        path->narrow = FALSE;
1247
#else
1248
15.7k
        path->narrow = NULL;
1249
15.7k
#endif
1250
15.7k
        goto success_exit;
1251
15.7k
    }
1252
0
    else {
1253
12
 error_format:
1254
12
        PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1255
12
            path->function_name ? path->function_name : "",
  Branch (1255:13): [True: 12, False: 0]
1256
12
            path->function_name ? ": "                : "",
  Branch (1256:13): [True: 12, False: 0]
1257
12
            path->argument_name ? path->argument_name : "path",
  Branch (1257:13): [True: 12, False: 0]
1258
12
            path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
  Branch (1258:13): [True: 7, False: 5]
  Branch (1258:31): [True: 3, False: 4]
1259
3
                                               "integer or None" :
1260
12
            path->allow_fd ? "string, bytes, os.PathLike or integer" :
  Branch (1260:13): [True: 4, False: 5]
1261
9
            path->nullable ? "string, bytes, os.PathLike or None" :
  Branch (1261:13): [True: 0, False: 5]
1262
5
                             "string, bytes or os.PathLike",
1263
12
            _PyType_Name(Py_TYPE(o)));
Line
Count
Source
138
12
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
12
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
12
#  define _Py_CAST(type, expr) ((type)(expr))
1264
12
        goto error_exit;
1265
0
    }
1266
1267
559k
    length = PyBytes_GET_SIZE(bytes);
Line
Count
Source
45
559k
#define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self))
Line
Count
Source
109
559k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
559k
#  define _Py_CAST(type, expr) ((type)(expr))
1268
559k
    narrow = PyBytes_AS_STRING(bytes);
Line
Count
Source
39
559k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
559k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
559k
#  define _Py_CAST(type, expr) ((type)(expr))
1269
559k
    if ((size_t)length != strlen(narrow)) {
  Branch (1269:9): [True: 25, False: 559k]
1270
25
        FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Line
Count
Source
1122
25
    PyErr_Format(exc, "%s%s" fmt, \
1123
25
        path->function_name ? path->function_name : "", \
  Branch (1123:9): [True: 25, False: 0]
1124
25
        path->function_name ? ": "                : "", \
  Branch (1124:9): [True: 25, False: 0]
1125
25
        path->argument_name ? path->argument_name : "path")
  Branch (1125:9): [True: 25, False: 0]
1271
25
        goto error_exit;
1272
25
    }
1273
1274
#ifdef MS_WINDOWS
1275
    wo = PyUnicode_DecodeFSDefaultAndSize(
1276
        narrow,
1277
        length
1278
    );
1279
    if (!wo) {
1280
        goto error_exit;
1281
    }
1282
1283
    wide = PyUnicode_AsWideCharString(wo, &length);
1284
    Py_DECREF(wo);
1285
    if (!wide) {
1286
        goto error_exit;
1287
    }
1288
    if (length > 32767) {
1289
        FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
1290
        goto error_exit;
1291
    }
1292
    if (wcslen(wide) != length) {
1293
        FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
1294
        goto error_exit;
1295
    }
1296
    path->wide = wide;
1297
    path->narrow = TRUE;
1298
    Py_DECREF(bytes);
1299
    wide = NULL;
1300
#else
1301
559k
    path->wide = NULL;
1302
559k
    path->narrow = narrow;
1303
559k
    if (bytes == o) {
  Branch (1303:9): [True: 18.2k, False: 540k]
1304
        /* Still a reference owned by path->object, don't have to
1305
           worry about path->narrow is used after free. */
1306
18.2k
        Py_DECREF(bytes);
Line
Count
Source
548
18.2k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
18.2k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
18.2k
#  define _Py_CAST(type, expr) ((type)(expr))
1307
18.2k
    }
1308
540k
    else {
1309
540k
        path->cleanup = bytes;
1310
540k
    }
1311
559k
#endif
1312
559k
    path->fd = -1;
1313
1314
574k
 success_exit:
1315
574k
    path->length = length;
1316
574k
    path->object = o;
1317
574k
    return Py_CLEANUP_SUPPORTED;
Line
Count
Source
69
574k
#define Py_CLEANUP_SUPPORTED 0x20000
1318
1319
150
 error_exit:
1320
150
    Py_XDECREF(o);
Line
Count
Source
613
150
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
150
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
150
#  define _Py_CAST(type, expr) ((type)(expr))
1321
150
    Py_XDECREF(bytes);
Line
Count
Source
613
150
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
150
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
150
#  define _Py_CAST(type, expr) ((type)(expr))
1322
#ifdef MS_WINDOWS
1323
    PyMem_Free(wide);
1324
#endif
1325
150
    return 0;
1326
559k
}
1327
1328
static void
1329
argument_unavailable_error(const char *function_name, const char *argument_name)
1330
0
{
1331
0
    PyErr_Format(PyExc_NotImplementedError,
1332
0
        "%s%s%s unavailable on this platform",
1333
0
        (function_name != NULL) ? function_name : "",
  Branch (1333:9): [True: 0, False: 0]
1334
0
        (function_name != NULL) ? ": ": "",
  Branch (1334:9): [True: 0, False: 0]
1335
0
        argument_name);
1336
0
}
1337
1338
static int
1339
dir_fd_unavailable(PyObject *o, void *p)
1340
278
{
1341
278
    int dir_fd;
1342
278
    if (!dir_fd_converter(o, &dir_fd))
  Branch (1342:9): [True: 0, False: 278]
1343
0
        return 0;
1344
278
    if (dir_fd != DEFAULT_DIR_FD) {
Line
Count
Source
904
278
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (1344:9): [True: 0, False: 278]
1345
0
        argument_unavailable_error(NULL, "dir_fd");
1346
0
        return 0;
1347
0
    }
1348
278
    *(int *)p = dir_fd;
1349
278
    return 1;
1350
278
}
1351
1352
static int
1353
fd_specified(const char *function_name, int fd)
1354
278
{
1355
278
    if (fd == -1)
  Branch (1355:9): [True: 278, False: 0]
1356
278
        return 0;
1357
1358
0
    argument_unavailable_error(function_name, "fd");
1359
0
    return 1;
1360
278
}
1361
1362
static int
1363
follow_symlinks_specified(const char *function_name, int follow_symlinks)
1364
278
{
1365
278
    if (follow_symlinks)
  Branch (1365:9): [True: 278, False: 0]
1366
278
        return 0;
1367
1368
0
    argument_unavailable_error(function_name, "follow_symlinks");
1369
0
    return 1;
1370
278
}
1371
1372
static int
1373
path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1374
406k
{
1375
406k
    if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
Line
Count
Source
904
406k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (1375:9): [True: 406k, False: 0]
  Branch (1375:24): [True: 3.85k, False: 402k]
1376
406k
#ifndef MS_WINDOWS
1377
406k
        && !path->narrow
  Branch (1377:12): [True: 0, False: 3.85k]
1378
406k
#endif
1379
406k
    ) {
1380
0
        PyErr_Format(PyExc_ValueError,
1381
0
                     "%s: can't specify dir_fd without matching path",
1382
0
                     function_name);
1383
0
        return 1;
1384
0
    }
1385
406k
    return 0;
1386
406k
}
1387
1388
static int
1389
dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1390
406k
{
1391
406k
    if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
Line
Count
Source
904
406k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (1391:9): [True: 3.85k, False: 402k]
  Branch (1391:39): [True: 0, False: 3.85k]
1392
0
        PyErr_Format(PyExc_ValueError,
1393
0
                     "%s: can't specify both dir_fd and fd",
1394
0
                     function_name);
1395
0
        return 1;
1396
0
    }
1397
406k
    return 0;
1398
406k
}
1399
1400
static int
1401
fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1402
                               int follow_symlinks)
1403
416k
{
1404
416k
    if ((fd > 0) && (!follow_symlinks)) {
  Branch (1404:9): [True: 4.01k, False: 412k]
  Branch (1404:21): [True: 0, False: 4.01k]
1405
0
        PyErr_Format(PyExc_ValueError,
1406
0
                     "%s: cannot use fd and follow_symlinks together",
1407
0
                     function_name);
1408
0
        return 1;
1409
0
    }
1410
416k
    return 0;
1411
416k
}
1412
1413
static int
1414
dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1415
                                   int follow_symlinks)
1416
278
{
1417
278
    if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Line
Count
Source
904
278
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (1417:9): [True: 0, False: 278]
  Branch (1417:39): [True: 0, False: 0]
1418
0
        PyErr_Format(PyExc_ValueError,
1419
0
                     "%s: cannot use dir_fd and follow_symlinks together",
1420
0
                     function_name);
1421
0
        return 1;
1422
0
    }
1423
278
    return 0;
1424
278
}
1425
1426
#ifdef MS_WINDOWS
1427
    typedef long long Py_off_t;
1428
#else
1429
    typedef off_t Py_off_t;
1430
#endif
1431
1432
static int
1433
Py_off_t_converter(PyObject *arg, void *addr)
1434
25.9k
{
1435
#ifdef HAVE_LARGEFILE_SUPPORT
1436
    *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1437
#else
1438
25.9k
    *((Py_off_t *)addr) = PyLong_AsLong(arg);
1439
25.9k
#endif
1440
25.9k
    if (PyErr_Occurred())
  Branch (1440:9): [True: 0, False: 25.9k]
1441
0
        return 0;
1442
25.9k
    return 1;
1443
25.9k
}
1444
1445
static PyObject *
1446
PyLong_FromPy_off_t(Py_off_t offset)
1447
8.35k
{
1448
#ifdef HAVE_LARGEFILE_SUPPORT
1449
    return PyLong_FromLongLong(offset);
1450
#else
1451
8.35k
    return PyLong_FromLong(offset);
1452
8.35k
#endif
1453
8.35k
}
1454
1455
#ifdef HAVE_SIGSET_T
1456
/* Convert an iterable of integers to a sigset.
1457
   Return 1 on success, return 0 and raise an exception on error. */
1458
int
1459
_Py_Sigset_Converter(PyObject *obj, void *addr)
1460
96
{
1461
96
    sigset_t *mask = (sigset_t *)addr;
1462
96
    PyObject *iterator, *item;
1463
96
    long signum;
1464
96
    int overflow;
1465
1466
    // The extra parens suppress the unreachable-code warning with clang on MacOS
1467
96
    if (sigemptyset(mask) < (0)) {
  Branch (1467:9): [True: 0, False: 96]
1468
        /* Probably only if mask == NULL. */
1469
0
        PyErr_SetFromErrno(PyExc_OSError);
1470
0
        return 0;
1471
0
    }
1472
1473
96
    iterator = PyObject_GetIter(obj);
1474
96
    if (iterator == NULL) {
  Branch (1474:9): [True: 4, False: 92]
1475
4
        return 0;
1476
4
    }
1477
1478
533
    while ((item = PyIter_Next(iterator)) != NULL) {
  Branch (1478:12): [True: 452, False: 81]
1479
452
        signum = PyLong_AsLongAndOverflow(item, &overflow);
1480
452
        Py_DECREF(item);
Line
Count
Source
548
452
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
452
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
452
#  define _Py_CAST(type, expr) ((type)(expr))
1481
452
        if (signum <= 0 || signum >= Py_NSIG) {
Line
Count
Source
21
446
#  define Py_NSIG NSIG
  Branch (1481:13): [True: 6, False: 446]
  Branch (1481:28): [True: 5, False: 441]
1482
11
            if (overflow || signum != -1 || !PyErr_Occurred()) {
  Branch (1482:17): [True: 1, False: 10]
  Branch (1482:29): [True: 6, False: 4]
  Branch (1482:45): [True: 0, False: 4]
1483
7
                PyErr_Format(PyExc_ValueError,
1484
7
                             "signal number %ld out of range [1; %i]",
1485
7
                             signum, Py_NSIG - 1);
Line
Count
Source
21
7
#  define Py_NSIG NSIG
1486
7
            }
1487
11
            goto error;
1488
11
        }
1489
441
        if (sigaddset(mask, (int)signum)) {
  Branch (1489:13): [True: 0, False: 441]
1490
0
            if (errno != EINVAL) {
  Branch (1490:17): [True: 0, False: 0]
1491
                /* Probably impossible */
1492
0
                PyErr_SetFromErrno(PyExc_OSError);
1493
0
                goto error;
1494
0
            }
1495
            /* For backwards compatibility, allow idioms such as
1496
             * `range(1, NSIG)` but warn about invalid signal numbers
1497
             */
1498
0
            const char msg[] =
1499
0
                "invalid signal number %ld, please use valid_signals()";
1500
0
            if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
  Branch (1500:17): [True: 0, False: 0]
1501
0
                goto error;
1502
0
            }
1503
0
        }
1504
441
    }
1505
81
    if (!PyErr_Occurred()) {
  Branch (1505:9): [True: 81, False: 0]
1506
81
        Py_DECREF(iterator);
Line
Count
Source
548
81
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
81
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
81
#  define _Py_CAST(type, expr) ((type)(expr))
1507
81
        return 1;
1508
81
    }
1509
1510
11
error:
1511
11
    Py_DECREF(iterator);
Line
Count
Source
548
11
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
11
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
11
#  define _Py_CAST(type, expr) ((type)(expr))
1512
11
    return 0;
1513
81
}
1514
#endif /* HAVE_SIGSET_T */
1515
1516
#ifdef MS_WINDOWS
1517
1518
static int
1519
win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
1520
{
1521
    char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1522
    _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
1523
    DWORD n_bytes_returned;
1524
1525
    if (0 == DeviceIoControl(
1526
        reparse_point_handle,
1527
        FSCTL_GET_REPARSE_POINT,
1528
        NULL, 0, /* in buffer */
1529
        target_buffer, sizeof(target_buffer),
1530
        &n_bytes_returned,
1531
        NULL)) /* we're not using OVERLAPPED_IO */
1532
        return FALSE;
1533
1534
    if (reparse_tag)
1535
        *reparse_tag = rdb->ReparseTag;
1536
1537
    return TRUE;
1538
}
1539
1540
#endif /* MS_WINDOWS */
1541
1542
/* Return a dictionary corresponding to the POSIX environment table */
1543
#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1544
/* On Darwin/MacOSX a shared library or framework has no access to
1545
** environ directly, we must obtain it with _NSGetEnviron(). See also
1546
** man environ(7).
1547
*/
1548
#include <crt_externs.h>
1549
#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
1550
extern char **environ;
1551
#endif /* !_MSC_VER */
1552
1553
static PyObject *
1554
convertenviron(void)
1555
278
{
1556
278
    PyObject *d;
1557
#ifdef MS_WINDOWS
1558
    wchar_t **e;
1559
#else
1560
278
    char **e;
1561
278
#endif
1562
1563
278
    d = PyDict_New();
1564
278
    if (d == NULL)
  Branch (1564:9): [True: 0, False: 278]
1565
0
        return NULL;
1566
#ifdef MS_WINDOWS
1567
    /* _wenviron must be initialized in this way if the program is started
1568
       through main() instead of wmain(). */
1569
    _wgetenv(L"");
1570
    e = _wenviron;
1571
#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1572
    /* environ is not accessible as an extern in a shared object on OSX; use
1573
       _NSGetEnviron to resolve it. The value changes if you add environment
1574
       variables between calls to Py_Initialize, so don't cache the value. */
1575
    e = *_NSGetEnviron();
1576
#else
1577
278
    e = environ;
1578
278
#endif
1579
278
    if (e == NULL)
  Branch (1579:9): [True: 0, False: 278]
1580
0
        return d;
1581
19.3k
    for (; *e != NULL; e++) {
  Branch (1581:12): [True: 19.0k, False: 278]
1582
19.0k
        PyObject *k;
1583
19.0k
        PyObject *v;
1584
#ifdef MS_WINDOWS
1585
        const wchar_t *p = wcschr(*e, L'=');
1586
#else
1587
19.0k
        const char *p = strchr(*e, '=');
1588
19.0k
#endif
1589
19.0k
        if (p == NULL)
  Branch (1589:13): [True: 0, False: 19.0k]
1590
0
            continue;
1591
#ifdef MS_WINDOWS
1592
        k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1593
#else
1594
19.0k
        k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
1595
19.0k
#endif
1596
19.0k
        if (k == NULL) {
  Branch (1596:13): [True: 0, False: 19.0k]
1597
0
            Py_DECREF(d);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
1598
0
            return NULL;
1599
0
        }
1600
#ifdef MS_WINDOWS
1601
        v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1602
#else
1603
19.0k
        v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
1604
19.0k
#endif
1605
19.0k
        if (v == NULL) {
  Branch (1605:13): [True: 0, False: 19.0k]
1606
0
            Py_DECREF(k);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
1607
0
            Py_DECREF(d);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
1608
0
            return NULL;
1609
0
        }
1610
19.0k
        if (PyDict_SetDefault(d, k, v) == NULL) {
  Branch (1610:13): [True: 0, False: 19.0k]
1611
0
            Py_DECREF(v);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
1612
0
            Py_DECREF(k);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
1613
0
            Py_DECREF(d);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
1614
0
            return NULL;
1615
0
        }
1616
19.0k
        Py_DECREF(k);
Line
Count
Source
548
19.0k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
19.0k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19.0k
#  define _Py_CAST(type, expr) ((type)(expr))
1617
19.0k
        Py_DECREF(v);
Line
Count
Source
548
19.0k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
19.0k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19.0k
#  define _Py_CAST(type, expr) ((type)(expr))
1618
19.0k
    }
1619
278
    return d;
1620
278
}
1621
1622
/* Set a POSIX-specific error from errno, and return NULL */
1623
1624
static PyObject *
1625
posix_error(void)
1626
3.61k
{
1627
3.61k
    return PyErr_SetFromErrno(PyExc_OSError);
1628
3.61k
}
1629
1630
#ifdef MS_WINDOWS
1631
static PyObject *
1632
win32_error(const char* function, const char* filename)
1633
{
1634
    /* XXX We should pass the function name along in the future.
1635
       (winreg.c also wants to pass the function name.)
1636
       This would however require an additional param to the
1637
       Windows error object, which is non-trivial.
1638
    */
1639
    errno = GetLastError();
1640
    if (filename)
1641
        return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1642
    else
1643
        return PyErr_SetFromWindowsErr(errno);
1644
}
1645
1646
static PyObject *
1647
win32_error_object_err(const char* function, PyObject* filename, DWORD err)
1648
{
1649
    /* XXX - see win32_error for comments on 'function' */
1650
    if (filename)
1651
        return PyErr_SetExcFromWindowsErrWithFilenameObject(
1652
                    PyExc_OSError,
1653
                    err,
1654
                    filename);
1655
    else
1656
        return PyErr_SetFromWindowsErr(err);
1657
}
1658
1659
static PyObject *
1660
win32_error_object(const char* function, PyObject* filename)
1661
{
1662
    errno = GetLastError();
1663
    return win32_error_object_err(function, filename, errno);
1664
}
1665
1666
#endif /* MS_WINDOWS */
1667
1668
static PyObject *
1669
posix_path_object_error(PyObject *path)
1670
124k
{
1671
124k
    return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1672
124k
}
1673
1674
static PyObject *
1675
path_object_error(PyObject *path)
1676
124k
{
1677
#ifdef MS_WINDOWS
1678
    return PyErr_SetExcFromWindowsErrWithFilenameObject(
1679
                PyExc_OSError, 0, path);
1680
#else
1681
124k
    return posix_path_object_error(path);
1682
124k
#endif
1683
124k
}
1684
1685
static PyObject *
1686
path_object_error2(PyObject *path, PyObject *path2)
1687
127
{
1688
#ifdef MS_WINDOWS
1689
    return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1690
                PyExc_OSError, 0, path, path2);
1691
#else
1692
127
    return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1693
127
#endif
1694
127
}
1695
1696
static PyObject *
1697
path_error(path_t *path)
1698
122k
{
1699
122k
    return path_object_error(path->object);
1700
122k
}
1701
1702
static PyObject *
1703
posix_path_error(path_t *path)
1704
5
{
1705
5
    return posix_path_object_error(path->object);
1706
5
}
1707
1708
static PyObject *
1709
path_error2(path_t *path, path_t *path2)
1710
127
{
1711
127
    return path_object_error2(path->object, path2->object);
1712
127
}
1713
1714
1715
/* POSIX generic methods */
1716
1717
static PyObject *
1718
posix_fildes_fd(int fd, int (*func)(int))
1719
545
{
1720
545
    int res;
1721
545
    int async_err = 0;
1722
1723
545
    do {
1724
545
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
545
#define Py_BEGIN_ALLOW_THREADS { \
143
545
                        PyThreadState *_save; \
144
545
                        _save = PyEval_SaveThread();
1725
545
        _Py_BEGIN_SUPPRESS_IPH
1726
545
        res = (*func)(fd);
1727
545
        _Py_END_SUPPRESS_IPH
1728
545
        Py_END_ALLOW_THREADS
Line
Count
Source
147
545
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
545
                 }
1729
545
    } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (1729:14): [True: 3, False: 542]
  Branch (1729:26): [True: 0, False: 3]
  Branch (1729:44): [True: 0, False: 0]
1730
545
    if (res != 0)
  Branch (1730:9): [True: 3, False: 542]
1731
3
        return (!async_err) ? posix_error() : NULL;
  Branch (1731:16): [True: 3, False: 0]
1732
545
    Py_RETURN_NONE;
Line
Count
Source
661
542
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
542
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
542
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
542
#  define _Py_CAST(type, expr) ((type)(expr))
1733
545
}
1734
1735
1736
#ifdef MS_WINDOWS
1737
/* This is a reimplementation of the C library's chdir function,
1738
   but one that produces Win32 errors instead of DOS error codes.
1739
   chdir is essentially a wrapper around SetCurrentDirectory; however,
1740
   it also needs to set "magic" environment variables indicating
1741
   the per-drive current directory, which are of the form =<drive>: */
1742
static BOOL __stdcall
1743
win32_wchdir(LPCWSTR path)
1744
{
1745
    wchar_t path_buf[MAX_PATH], *new_path = path_buf;
1746
    int result;
1747
    wchar_t env[4] = L"=x:";
1748
1749
    if(!SetCurrentDirectoryW(path))
1750
        return FALSE;
1751
    result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
1752
    if (!result)
1753
        return FALSE;
1754
    if (result > Py_ARRAY_LENGTH(path_buf)) {
1755
        new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
1756
        if (!new_path) {
1757
            SetLastError(ERROR_OUTOFMEMORY);
1758
            return FALSE;
1759
        }
1760
        result = GetCurrentDirectoryW(result, new_path);
1761
        if (!result) {
1762
            PyMem_RawFree(new_path);
1763
            return FALSE;
1764
        }
1765
    }
1766
    int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1767
                            wcsncmp(new_path, L"//", 2) == 0);
1768
    if (!is_unc_like_path) {
1769
        env[1] = new_path[0];
1770
        result = SetEnvironmentVariableW(env, new_path);
1771
    }
1772
    if (new_path != path_buf)
1773
        PyMem_RawFree(new_path);
1774
    return result ? TRUE : FALSE;
1775
}
1776
#endif
1777
1778
#ifdef MS_WINDOWS
1779
/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1780
   - time stamps are restricted to second resolution
1781
   - file modification times suffer from forth-and-back conversions between
1782
     UTC and local time
1783
   Therefore, we implement our own stat, based on the Win32 API directly.
1784
*/
1785
#define HAVE_STAT_NSEC 1
1786
#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
1787
#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
1788
1789
static void
1790
find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1791
                       BY_HANDLE_FILE_INFORMATION *info,
1792
                       ULONG *reparse_tag)
1793
{
1794
    memset(info, 0, sizeof(*info));
1795
    info->dwFileAttributes = pFileData->dwFileAttributes;
1796
    info->ftCreationTime   = pFileData->ftCreationTime;
1797
    info->ftLastAccessTime = pFileData->ftLastAccessTime;
1798
    info->ftLastWriteTime  = pFileData->ftLastWriteTime;
1799
    info->nFileSizeHigh    = pFileData->nFileSizeHigh;
1800
    info->nFileSizeLow     = pFileData->nFileSizeLow;
1801
/*  info->nNumberOfLinks   = 1; */
1802
    if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1803
        *reparse_tag = pFileData->dwReserved0;
1804
    else
1805
        *reparse_tag = 0;
1806
}
1807
1808
static BOOL
1809
attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
1810
{
1811
    HANDLE hFindFile;
1812
    WIN32_FIND_DATAW FileData;
1813
    LPCWSTR filename = pszFile;
1814
    size_t n = wcslen(pszFile);
1815
    if (n && (pszFile[n - 1] == L'\\' || pszFile[n - 1] == L'/')) {
1816
        // cannot use PyMem_Malloc here because we do not hold the GIL
1817
        filename = (LPCWSTR)malloc((n + 1) * sizeof(filename[0]));
1818
        wcsncpy_s((LPWSTR)filename, n + 1, pszFile, n);
1819
        while (--n > 0 && (filename[n] == L'\\' || filename[n] == L'/')) {
1820
            ((LPWSTR)filename)[n] = L'\0';
1821
        }
1822
        if (!n || (n == 1 && filename[1] == L':')) {
1823
            // Nothing left to query
1824
            free((void *)filename);
1825
            return FALSE;
1826
        }
1827
    }
1828
    hFindFile = FindFirstFileW(filename, &FileData);
1829
    if (pszFile != filename) {
1830
        free((void *)filename);
1831
    }
1832
    if (hFindFile == INVALID_HANDLE_VALUE) {
1833
        return FALSE;
1834
    }
1835
    FindClose(hFindFile);
1836
    find_data_to_file_info(&FileData, info, reparse_tag);
1837
    return TRUE;
1838
}
1839
1840
static int
1841
win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
1842
                 BOOL traverse)
1843
{
1844
    HANDLE hFile;
1845
    BY_HANDLE_FILE_INFORMATION fileInfo;
1846
    FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1847
    DWORD fileType, error;
1848
    BOOL isUnhandledTag = FALSE;
1849
    int retval = 0;
1850
1851
    DWORD access = FILE_READ_ATTRIBUTES;
1852
    DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1853
    if (!traverse) {
1854
        flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1855
    }
1856
1857
    hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
1858
    if (hFile == INVALID_HANDLE_VALUE) {
1859
        /* Either the path doesn't exist, or the caller lacks access. */
1860
        error = GetLastError();
1861
        switch (error) {
1862
        case ERROR_ACCESS_DENIED:     /* Cannot sync or read attributes. */
1863
        case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1864
            /* Try reading the parent directory. */
1865
            if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1866
                /* Cannot read the parent directory. */
1867
                switch (GetLastError()) {
1868
                case ERROR_FILE_NOT_FOUND: /* File cannot be found */
1869
                case ERROR_PATH_NOT_FOUND: /* File parent directory cannot be found */
1870
                case ERROR_NOT_READY: /* Drive exists but unavailable */
1871
                case ERROR_BAD_NET_NAME: /* Remote drive unavailable */
1872
                    break;
1873
                /* Restore the error from CreateFileW(). */
1874
                default:
1875
                    SetLastError(error);
1876
                }
1877
1878
                return -1;
1879
            }
1880
            if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1881
                if (traverse ||
1882
                    !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1883
                    /* The stat call has to traverse but cannot, so fail. */
1884
                    SetLastError(error);
1885
                    return -1;
1886
                }
1887
            }
1888
            break;
1889
1890
        case ERROR_INVALID_PARAMETER:
1891
            /* \\.\con requires read or write access. */
1892
            hFile = CreateFileW(path, access | GENERIC_READ,
1893
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1894
                        OPEN_EXISTING, flags, NULL);
1895
            if (hFile == INVALID_HANDLE_VALUE) {
1896
                SetLastError(error);
1897
                return -1;
1898
            }
1899
            break;
1900
1901
        case ERROR_CANT_ACCESS_FILE:
1902
            /* bpo37834: open unhandled reparse points if traverse fails. */
1903
            if (traverse) {
1904
                traverse = FALSE;
1905
                isUnhandledTag = TRUE;
1906
                hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1907
                            flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1908
            }
1909
            if (hFile == INVALID_HANDLE_VALUE) {
1910
                SetLastError(error);
1911
                return -1;
1912
            }
1913
            break;
1914
1915
        default:
1916
            return -1;
1917
        }
1918
    }
1919
1920
    if (hFile != INVALID_HANDLE_VALUE) {
1921
        /* Handle types other than files on disk. */
1922
        fileType = GetFileType(hFile);
1923
        if (fileType != FILE_TYPE_DISK) {
1924
            if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1925
                retval = -1;
1926
                goto cleanup;
1927
            }
1928
            DWORD fileAttributes = GetFileAttributesW(path);
1929
            memset(result, 0, sizeof(*result));
1930
            if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1931
                fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1932
                /* \\.\pipe\ or \\.\mailslot\ */
1933
                result->st_mode = _S_IFDIR;
1934
            } else if (fileType == FILE_TYPE_CHAR) {
1935
                /* \\.\nul */
1936
                result->st_mode = _S_IFCHR;
1937
            } else if (fileType == FILE_TYPE_PIPE) {
1938
                /* \\.\pipe\spam */
1939
                result->st_mode = _S_IFIFO;
1940
            }
1941
            /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1942
            goto cleanup;
1943
        }
1944
1945
        /* Query the reparse tag, and traverse a non-link. */
1946
        if (!traverse) {
1947
            if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1948
                    &tagInfo, sizeof(tagInfo))) {
1949
                /* Allow devices that do not support FileAttributeTagInfo. */
1950
                switch (GetLastError()) {
1951
                case ERROR_INVALID_PARAMETER:
1952
                case ERROR_INVALID_FUNCTION:
1953
                case ERROR_NOT_SUPPORTED:
1954
                    tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1955
                    tagInfo.ReparseTag = 0;
1956
                    break;
1957
                default:
1958
                    retval = -1;
1959
                    goto cleanup;
1960
                }
1961
            } else if (tagInfo.FileAttributes &
1962
                         FILE_ATTRIBUTE_REPARSE_POINT) {
1963
                if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1964
                    if (isUnhandledTag) {
1965
                        /* Traversing previously failed for either this link
1966
                           or its target. */
1967
                        SetLastError(ERROR_CANT_ACCESS_FILE);
1968
                        retval = -1;
1969
                        goto cleanup;
1970
                    }
1971
                /* Traverse a non-link, but not if traversing already failed
1972
                   for an unhandled tag. */
1973
                } else if (!isUnhandledTag) {
1974
                    CloseHandle(hFile);
1975
                    return win32_xstat_impl(path, result, TRUE);
1976
                }
1977
            }
1978
        }
1979
1980
        if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1981
            switch (GetLastError()) {
1982
            case ERROR_INVALID_PARAMETER:
1983
            case ERROR_INVALID_FUNCTION:
1984
            case ERROR_NOT_SUPPORTED:
1985
                /* Volumes and physical disks are block devices, e.g.
1986
                   \\.\C: and \\.\PhysicalDrive0. */
1987
                memset(result, 0, sizeof(*result));
1988
                result->st_mode = 0x6000; /* S_IFBLK */
1989
                goto cleanup;
1990
            }
1991
            retval = -1;
1992
            goto cleanup;
1993
        }
1994
    }
1995
1996
    _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
1997
1998
    if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
1999
        /* Fix the file execute permissions. This hack sets S_IEXEC if
2000
           the filename has an extension that is commonly used by files
2001
           that CreateProcessW can execute. A real implementation calls
2002
           GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
2003
           AccessCheck to check for generic read, write, and execute
2004
           access. */
2005
        const wchar_t *fileExtension = wcsrchr(path, '.');
2006
        if (fileExtension) {
2007
            if (_wcsicmp(fileExtension, L".exe") == 0 ||
2008
                _wcsicmp(fileExtension, L".bat") == 0 ||
2009
                _wcsicmp(fileExtension, L".cmd") == 0 ||
2010
                _wcsicmp(fileExtension, L".com") == 0) {
2011
                result->st_mode |= 0111;
2012
            }
2013
        }
2014
    }
2015
2016
cleanup:
2017
    if (hFile != INVALID_HANDLE_VALUE) {
2018
        /* Preserve last error if we are failing */
2019
        error = retval ? GetLastError() : 0;
2020
        if (!CloseHandle(hFile)) {
2021
            retval = -1;
2022
        } else if (retval) {
2023
            /* Restore last error */
2024
            SetLastError(error);
2025
        }
2026
    }
2027
2028
    return retval;
2029
}
2030
2031
static int
2032
win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
2033
{
2034
    /* Protocol violation: we explicitly clear errno, instead of
2035
       setting it to a POSIX error. Callers should use GetLastError. */
2036
    int code = win32_xstat_impl(path, result, traverse);
2037
    errno = 0;
2038
    return code;
2039
}
2040
/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
2041
2042
   In Posix, stat automatically traverses symlinks and returns the stat
2043
   structure for the target.  In Windows, the equivalent GetFileAttributes by
2044
   default does not traverse symlinks and instead returns attributes for
2045
   the symlink.
2046
2047
   Instead, we will open the file (which *does* traverse symlinks by default)
2048
   and GetFileInformationByHandle(). */
2049
2050
static int
2051
win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
2052
{
2053
    return win32_xstat(path, result, FALSE);
2054
}
2055
2056
static int
2057
win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
2058
{
2059
    return win32_xstat(path, result, TRUE);
2060
}
2061
2062
#endif /* MS_WINDOWS */
2063
2064
PyDoc_STRVAR(stat_result__doc__,
2065
"stat_result: Result from stat, fstat, or lstat.\n\n\
2066
This object may be accessed either as a tuple of\n\
2067
  (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
2068
or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
2069
\n\
2070
Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
2071
or st_flags, they are available as attributes only.\n\
2072
\n\
2073
See os.stat for more information.");
2074
2075
static PyStructSequence_Field stat_result_fields[] = {
2076
    {"st_mode",    "protection bits"},
2077
    {"st_ino",     "inode"},
2078
    {"st_dev",     "device"},
2079
    {"st_nlink",   "number of hard links"},
2080
    {"st_uid",     "user ID of owner"},
2081
    {"st_gid",     "group ID of owner"},
2082
    {"st_size",    "total size, in bytes"},
2083
    /* The NULL is replaced with PyStructSequence_UnnamedField later. */
2084
    {NULL,   "integer time of last access"},
2085
    {NULL,   "integer time of last modification"},
2086
    {NULL,   "integer time of last change"},
2087
    {"st_atime",   "time of last access"},
2088
    {"st_mtime",   "time of last modification"},
2089
    {"st_ctime",   "time of last change"},
2090
    {"st_atime_ns",   "time of last access in nanoseconds"},
2091
    {"st_mtime_ns",   "time of last modification in nanoseconds"},
2092
    {"st_ctime_ns",   "time of last change in nanoseconds"},
2093
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
2094
    {"st_blksize", "blocksize for filesystem I/O"},
2095
#endif
2096
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
2097
    {"st_blocks",  "number of blocks allocated"},
2098
#endif
2099
#ifdef HAVE_STRUCT_STAT_ST_RDEV
2100
    {"st_rdev",    "device type (if inode device)"},
2101
#endif
2102
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2103
    {"st_flags",   "user defined flags for file"},
2104
#endif
2105
#ifdef HAVE_STRUCT_STAT_ST_GEN
2106
    {"st_gen",    "generation number"},
2107
#endif
2108
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2109
    {"st_birthtime",   "time of creation"},
2110
#endif
2111
#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2112
    {"st_file_attributes", "Windows file attribute bits"},
2113
#endif
2114
#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2115
    {"st_fstype",  "Type of filesystem"},
2116
#endif
2117
#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2118
    {"st_reparse_tag", "Windows reparse tag"},
2119
#endif
2120
    {0}
2121
};
2122
2123
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
2124
#define ST_BLKSIZE_IDX 16
2125
#else
2126
#define ST_BLKSIZE_IDX 15
2127
#endif
2128
2129
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
2130
#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2131
#else
2132
#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2133
#endif
2134
2135
#ifdef HAVE_STRUCT_STAT_ST_RDEV
2136
#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2137
#else
2138
#define ST_RDEV_IDX ST_BLOCKS_IDX
2139
#endif
2140
2141
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2142
#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2143
#else
2144
#define ST_FLAGS_IDX ST_RDEV_IDX
2145
#endif
2146
2147
#ifdef HAVE_STRUCT_STAT_ST_GEN
2148
#define ST_GEN_IDX (ST_FLAGS_IDX+1)
2149
#else
2150
#define ST_GEN_IDX ST_FLAGS_IDX
2151
#endif
2152
2153
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2154
#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2155
#else
2156
#define ST_BIRTHTIME_IDX ST_GEN_IDX
2157
#endif
2158
2159
#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2160
#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2161
#else
2162
#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2163
#endif
2164
2165
#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2166
#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2167
#else
2168
#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2169
#endif
2170
2171
#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2172
#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2173
#else
2174
#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2175
#endif
2176
2177
static PyStructSequence_Desc stat_result_desc = {
2178
    "stat_result", /* name */
2179
    stat_result__doc__, /* doc */
2180
    stat_result_fields,
2181
    10
2182
};
2183
2184
PyDoc_STRVAR(statvfs_result__doc__,
2185
"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2186
This object may be accessed either as a tuple of\n\
2187
  (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
2188
or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
2189
\n\
2190
See os.statvfs for more information.");
2191
2192
static PyStructSequence_Field statvfs_result_fields[] = {
2193
    {"f_bsize",  },
2194
    {"f_frsize", },
2195
    {"f_blocks", },
2196
    {"f_bfree",  },
2197
    {"f_bavail", },
2198
    {"f_files",  },
2199
    {"f_ffree",  },
2200
    {"f_favail", },
2201
    {"f_flag",   },
2202
    {"f_namemax",},
2203
    {"f_fsid",   },
2204
    {0}
2205
};
2206
2207
static PyStructSequence_Desc statvfs_result_desc = {
2208
    "statvfs_result", /* name */
2209
    statvfs_result__doc__, /* doc */
2210
    statvfs_result_fields,
2211
    10
2212
};
2213
2214
#if defined(HAVE_WAITID) && !defined(__APPLE__)
2215
PyDoc_STRVAR(waitid_result__doc__,
2216
"waitid_result: Result from waitid.\n\n\
2217
This object may be accessed either as a tuple of\n\
2218
  (si_pid, si_uid, si_signo, si_status, si_code),\n\
2219
or via the attributes si_pid, si_uid, and so on.\n\
2220
\n\
2221
See os.waitid for more information.");
2222
2223
static PyStructSequence_Field waitid_result_fields[] = {
2224
    {"si_pid",  },
2225
    {"si_uid", },
2226
    {"si_signo", },
2227
    {"si_status",  },
2228
    {"si_code", },
2229
    {0}
2230
};
2231
2232
static PyStructSequence_Desc waitid_result_desc = {
2233
    "waitid_result", /* name */
2234
    waitid_result__doc__, /* doc */
2235
    waitid_result_fields,
2236
    5
2237
};
2238
#endif
2239
static newfunc structseq_new;
2240
2241
static PyObject *
2242
statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2243
66
{
2244
66
    PyStructSequence *result;
2245
66
    int i;
2246
2247
66
    result = (PyStructSequence*)structseq_new(type, args, kwds);
2248
66
    if (!result)
  Branch (2248:9): [True: 2, False: 64]
2249
2
        return NULL;
2250
    /* If we have been initialized from a tuple,
2251
       st_?time might be set to None. Initialize it
2252
       from the int slots.  */
2253
256
    for (i = 7; i <= 9; i++) {
  Branch (2253:17): [True: 192, False: 64]
2254
192
        if (result->ob_item[i+3] == Py_None) {
Line
Count
Source
654
192
#define Py_None (&_Py_NoneStruct)
  Branch (2254:13): [True: 60, False: 132]
2255
60
            Py_DECREF(Py_None);
Line
Count
Source
548
60
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
60
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
60
#  define _Py_CAST(type, expr) ((type)(expr))
2256
60
            Py_INCREF(result->ob_item[i]);
Line
Count
Source
512
60
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
60
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
60
#  define _Py_CAST(type, expr) ((type)(expr))
2257
60
            result->ob_item[i+3] = result->ob_item[i];
2258
60
        }
2259
192
    }
2260
64
    return (PyObject*)result;
2261
66
}
2262
2263
static int
2264
_posix_clear(PyObject *module)
2265
544
{
2266
544
    _posixstate *state = get_posix_state(module);
2267
544
    Py_CLEAR(state->billion);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2268
544
    Py_CLEAR(state->DirEntryType);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2269
544
    Py_CLEAR(state->ScandirIteratorType);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2270
544
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
2271
544
    Py_CLEAR(state->SchedParamType);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2272
544
#endif
2273
544
    Py_CLEAR(state->StatResultType);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2274
544
    Py_CLEAR(state->StatVFSResultType);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2275
544
    Py_CLEAR(state->TerminalSizeType);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2276
544
    Py_CLEAR(state->TimesResultType);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2277
544
    Py_CLEAR(state->UnameResultType);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2278
544
#if defined(HAVE_WAITID) && !defined(__APPLE__)
2279
544
    Py_CLEAR(state->WaitidResultType);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2280
544
#endif
2281
544
#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
2282
544
    Py_CLEAR(state->struct_rusage);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2283
544
#endif
2284
544
    Py_CLEAR(state->st_mode);
Line
Count
Source
587
544
    do {                                        \
588
544
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
544
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
544
#  define _Py_CAST(type, expr) ((type)(expr))
589
544
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 272, False: 272]
590
272
            (op) = NULL;                        \
591
272
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
272
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
272
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
272
#  define _Py_CAST(type, expr) ((type)(expr))
592
272
        }                                       \
593
544
    } while (0)
  Branch (593:14): [Folded - Ignored]
2285
544
    return 0;
2286
544
}
2287
2288
static int
2289
_posix_traverse(PyObject *module, visitproc visit, void *arg)
2290
26.1k
{
2291
26.1k
    _posixstate *state = get_posix_state(module);
2292
26.1k
    Py_VISIT(state->billion);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2293
26.1k
    Py_VISIT(state->DirEntryType);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2294
26.1k
    Py_VISIT(state->ScandirIteratorType);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2295
26.1k
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
2296
26.1k
    Py_VISIT(state->SchedParamType);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2297
26.1k
#endif
2298
26.1k
    Py_VISIT(state->StatResultType);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2299
26.1k
    Py_VISIT(state->StatVFSResultType);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2300
26.1k
    Py_VISIT(state->TerminalSizeType);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2301
26.1k
    Py_VISIT(state->TimesResultType);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2302
26.1k
    Py_VISIT(state->UnameResultType);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2303
26.1k
#if defined(HAVE_WAITID) && !defined(__APPLE__)
2304
26.1k
    Py_VISIT(state->WaitidResultType);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2305
26.1k
#endif
2306
26.1k
#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
2307
26.1k
    Py_VISIT(state->struct_rusage);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2308
26.1k
#endif
2309
26.1k
    Py_VISIT(state->st_mode);
Line
Count
Source
198
26.1k
    do {                                                                \
199
26.1k
        if (op) {                                                       \
  Branch (199:13): [True: 26.1k, False: 0]
200
26.1k
            int vret = visit(_PyObject_CAST(op), arg);                  \
Line
Count
Source
109
26.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
26.1k
#  define _Py_CAST(type, expr) ((type)(expr))
201
26.1k
            if (vret)                                                   \
  Branch (201:17): [True: 0, False: 26.1k]
202
26.1k
                return vret;                                            \
203
26.1k
        }                                                               \
204
26.1k
    } while (0)
  Branch (204:14): [Folded - Ignored]
2310
26.1k
    return 0;
2311
26.1k
}
2312
2313
static void
2314
_posix_free(void *module)
2315
272
{
2316
272
   _posix_clear((PyObject *)module);
2317
272
}
2318
2319
static void
2320
fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
2321
979k
{
2322
979k
    PyObject *s = _PyLong_FromTime_t(sec);
2323
979k
    PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2324
979k
    PyObject *s_in_ns = NULL;
2325
979k
    PyObject *ns_total = NULL;
2326
979k
    PyObject *float_s = NULL;
2327
2328
979k
    if (!(s && ns_fractional))
  Branch (2328:11): [True: 979k, False: 0]
  Branch (2328:16): [True: 979k, False: 0]
2329
0
        goto exit;
2330
2331
979k
    s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
2332
979k
    if (!s_in_ns)
  Branch (2332:9): [True: 0, False: 979k]
2333
0
        goto exit;
2334
2335
979k
    ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2336
979k
    if (!ns_total)
  Branch (2336:9): [True: 0, False: 979k]
2337
0
        goto exit;
2338
2339
979k
    float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2340
979k
    if (!float_s) {
  Branch (2340:9): [True: 0, False: 979k]
2341
0
        goto exit;
2342
0
    }
2343
2344
979k
    PyStructSequence_SET_ITEM(v, index, s);
Line
Count
Source
38
979k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
979k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
2345
979k
    PyStructSequence_SET_ITEM(v, index+3, float_s);
Line
Count
Source
38
979k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
979k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
2346
979k
    PyStructSequence_SET_ITEM(v, index+6, ns_total);
Line
Count
Source
38
979k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
979k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
2347
979k
    s = NULL;
2348
979k
    float_s = NULL;
2349
979k
    ns_total = NULL;
2350
979k
exit:
2351
979k
    Py_XDECREF(s);
Line
Count
Source
613
979k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
2352
979k
    Py_XDECREF(ns_fractional);
Line
Count
Source
613
979k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
2353
979k
    Py_XDECREF(s_in_ns);
Line
Count
Source
613
979k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
2354
979k
    Py_XDECREF(ns_total);
Line
Count
Source
613
979k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
2355
979k
    Py_XDECREF(float_s);
Line
Count
Source
613
979k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
979k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
979k
#  define _Py_CAST(type, expr) ((type)(expr))
2356
979k
}
2357
2358
/* pack a system stat C structure into the Python stat tuple
2359
   (used by posix_stat() and posix_fstat()) */
2360
static PyObject*
2361
_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
2362
326k
{
2363
326k
    unsigned long ansec, mnsec, cnsec;
2364
326k
    PyObject *StatResultType = get_posix_state(module)->StatResultType;
2365
326k
    PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
2366
326k
    if (v == NULL)
  Branch (2366:9): [True: 0, False: 326k]
2367
0
        return NULL;
2368
2369
326k
    PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Line
Count
Source
38
326k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
326k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
2370
326k
    static_assert(sizeof(unsigned long long) >= sizeof(st->st_ino),
2371
326k
                  "stat.st_ino is larger than unsigned long long");
2372
326k
    PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Line
Count
Source
38
326k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
326k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
2373
#ifdef MS_WINDOWS
2374
    PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2375
#else
2376
326k
    PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Line
Count
Source
38
326k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
326k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
2377
326k
#endif
2378
326k
    PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Line
Count
Source
38
326k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
326k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
2379
#if defined(MS_WINDOWS)
2380
    PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2381
    PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2382
#else
2383
326k
    PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
Line
Count
Source
38
326k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
326k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
2384
326k
    PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
Line
Count
Source
38
326k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
326k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
2385
326k
#endif
2386
326k
    static_assert(sizeof(long long) >= sizeof(st->st_size),
2387
326k
                  "stat.st_size is larger than long long");
2388
326k
    PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Line
Count
Source
38
326k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
326k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
2389
2390
326k
#if defined(HAVE_STAT_TV_NSEC)
2391
326k
    ansec = st->st_atim.tv_nsec;
2392
326k
    mnsec = st->st_mtim.tv_nsec;
2393
326k
    cnsec = st->st_ctim.tv_nsec;
2394
#elif defined(HAVE_STAT_TV_NSEC2)
2395
    ansec = st->st_atimespec.tv_nsec;
2396
    mnsec = st->st_mtimespec.tv_nsec;
2397
    cnsec = st->st_ctimespec.tv_nsec;
2398
#elif defined(HAVE_STAT_NSEC)
2399
    ansec = st->st_atime_nsec;
2400
    mnsec = st->st_mtime_nsec;
2401
    cnsec = st->st_ctime_nsec;
2402
#else
2403
    ansec = mnsec = cnsec = 0;
2404
#endif
2405
326k
    fill_time(module, v, 7, st->st_atime, ansec);
2406
326k
    fill_time(module, v, 8, st->st_mtime, mnsec);
2407
326k
    fill_time(module, v, 9, st->st_ctime, cnsec);
2408
2409
326k
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
2410
326k
    PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Line
Count
Source
38
326k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
326k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
2411
326k
                              PyLong_FromLong((long)st->st_blksize));
2412
326k
#endif
2413
326k
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
2414
326k
    PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Line
Count
Source
38
326k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
326k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
2415
326k
                              PyLong_FromLong((long)st->st_blocks));
2416
326k
#endif
2417
326k
#ifdef HAVE_STRUCT_STAT_ST_RDEV
2418
326k
    PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Line
Count
Source
38
326k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
326k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
326k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
326k
#  define _Py_CAST(type, expr) ((type)(expr))
2419
326k
                              PyLong_FromLong((long)st->st_rdev));
2420
326k
#endif
2421
#ifdef HAVE_STRUCT_STAT_ST_GEN
2422
    PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2423
                              PyLong_FromLong((long)st->st_gen));
2424
#endif
2425
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2426
    {
2427
      PyObject *val;
2428
      unsigned long bsec,bnsec;
2429
      bsec = (long)st->st_birthtime;
2430
#ifdef HAVE_STAT_TV_NSEC2
2431
      bnsec = st->st_birthtimespec.tv_nsec;
2432
#else
2433
      bnsec = 0;
2434
#endif
2435
      val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2436
      PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2437
                                val);
2438
    }
2439
#endif
2440
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2441
    PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2442
                              PyLong_FromLong((long)st->st_flags));
2443
#endif
2444
#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2445
    PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2446
                              PyLong_FromUnsignedLong(st->st_file_attributes));
2447
#endif
2448
#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2449
   PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2450
                              PyUnicode_FromString(st->st_fstype));
2451
#endif
2452
#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2453
    PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2454
                              PyLong_FromUnsignedLong(st->st_reparse_tag));
2455
#endif
2456
2457
326k
    if (PyErr_Occurred()) {
  Branch (2457:9): [True: 0, False: 326k]
2458
0
        Py_DECREF(v);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
2459
0
        return NULL;
2460
0
    }
2461
2462
326k
    return v;
2463
326k
}
2464
2465
/* POSIX methods */
2466
2467
2468
static PyObject *
2469
posix_do_stat(PyObject *module, const char *function_name, path_t *path,
2470
              int dir_fd, int follow_symlinks)
2471
397k
{
2472
397k
    STRUCT_STAT st;
Line
Count
Source
473
397k
#  define STRUCT_STAT struct stat
2473
397k
    int result;
2474
2475
397k
#ifdef HAVE_FSTATAT
2476
397k
    int fstatat_unavailable = 0;
2477
397k
#endif
2478
2479
#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2480
    if (follow_symlinks_specified(function_name, follow_symlinks))
2481
        return NULL;
2482
#endif
2483
2484
397k
    if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
  Branch (2484:9): [True: 0, False: 397k]
2485
397k
        dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
  Branch (2485:9): [True: 0, False: 397k]
2486
397k
        fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
  Branch (2486:9): [True: 0, False: 397k]
2487
0
        return NULL;
2488
2489
397k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
397k
#define Py_BEGIN_ALLOW_THREADS { \
143
397k
                        PyThreadState *_save; \
144
397k
                        _save = PyEval_SaveThread();
2490
397k
    if (path->fd != -1)
  Branch (2490:9): [True: 3.76k, False: 393k]
2491
3.76k
        result = FSTAT(path->fd, &st);
Line
Count
Source
472
3.76k
#  define FSTAT fstat
2492
#ifdef MS_WINDOWS
2493
    else if (follow_symlinks)
2494
        result = win32_stat(path->wide, &st);
2495
    else
2496
        result = win32_lstat(path->wide, &st);
2497
#else
2498
393k
    else
2499
393k
#if defined(HAVE_LSTAT)
2500
393k
    if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Line
Count
Source
904
47.9k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (2500:9): [True: 47.9k, False: 346k]
  Branch (2500:31): [True: 44.1k, False: 3.80k]
2501
44.1k
        result = LSTAT(path->narrow, &st);
Line
Count
Source
471
44.1k
#  define LSTAT lstat
2502
349k
    else
2503
349k
#endif /* HAVE_LSTAT */
2504
349k
#ifdef HAVE_FSTATAT
2505
349k
    if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
Line
Count
Source
904
349k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (2505:9): [True: 3.84k, False: 346k]
  Branch (2505:39): [True: 0, False: 346k]
2506
3.84k
        if (HAVE_FSTATAT_RUNTIME) {
Line
Count
Source
163
3.84k
#  define HAVE_FSTATAT_RUNTIME 1
  Branch (163:32): [Folded - Ignored]
2507
3.84k
            result = fstatat(dir_fd, path->narrow, &st,
2508
3.84k
                         follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
  Branch (2508:26): [True: 41, False: 3.80k]
2509
2510
3.84k
        } else {
2511
0
            fstatat_unavailable = 1;
2512
0
        }
2513
3.84k
    } else
2514
346k
#endif /* HAVE_FSTATAT */
2515
346k
        result = STAT(path->narrow, &st);
Line
Count
Source
470
346k
#  define STAT stat
2516
397k
#endif /* MS_WINDOWS */
2517
397k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
397k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
397k
                 }
2518
2519
397k
#ifdef HAVE_FSTATAT
2520
397k
    if (fstatat_unavailable) {
  Branch (2520:9): [True: 0, False: 397k]
2521
0
        argument_unavailable_error("stat", "dir_fd");
2522
0
        return NULL;
2523
0
    }
2524
397k
#endif
2525
2526
397k
    if (result != 0) {
  Branch (2526:9): [True: 112k, False: 285k]
2527
112k
        return path_error(path);
2528
112k
    }
2529
2530
285k
    return _pystat_fromstructstat(module, &st);
2531
397k
}
2532
2533
/*[python input]
2534
2535
for s in """
2536
2537
FACCESSAT
2538
FCHMODAT
2539
FCHOWNAT
2540
FSTATAT
2541
LINKAT
2542
MKDIRAT
2543
MKFIFOAT
2544
MKNODAT
2545
OPENAT
2546
READLINKAT
2547
SYMLINKAT
2548
UNLINKAT
2549
2550
""".strip().split():
2551
    s = s.strip()
2552
    print("""
2553
#ifdef HAVE_{s}
2554
    #define {s}_DIR_FD_CONVERTER dir_fd_converter
2555
#else
2556
    #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
2557
#endif
2558
""".rstrip().format(s=s))
2559
2560
for s in """
2561
2562
FCHDIR
2563
FCHMOD
2564
FCHOWN
2565
FDOPENDIR
2566
FEXECVE
2567
FPATHCONF
2568
FSTATVFS
2569
FTRUNCATE
2570
2571
""".strip().split():
2572
    s = s.strip()
2573
    print("""
2574
#ifdef HAVE_{s}
2575
    #define PATH_HAVE_{s} 1
2576
#else
2577
    #define PATH_HAVE_{s} 0
2578
#endif
2579
2580
""".rstrip().format(s=s))
2581
[python start generated code]*/
2582
2583
#ifdef HAVE_FACCESSAT
2584
1
    #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2585
#else
2586
    #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2587
#endif
2588
2589
#ifdef HAVE_FCHMODAT
2590
1
    #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2591
#else
2592
    #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2593
#endif
2594
2595
#ifdef HAVE_FCHOWNAT
2596
1
    #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2597
#else
2598
    #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2599
#endif
2600
2601
#ifdef HAVE_FSTATAT
2602
7.21k
    #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2603
#else
2604
    #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2605
#endif
2606
2607
#ifdef HAVE_LINKAT
2608
    #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2609
#else
2610
    #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2611
#endif
2612
2613
#ifdef HAVE_MKDIRAT
2614
1
    #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2615
#else
2616
    #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2617
#endif
2618
2619
#ifdef HAVE_MKFIFOAT
2620
1
    #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2621
#else
2622
    #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2623
#endif
2624
2625
#ifdef HAVE_MKNODAT
2626
2
    #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2627
#else
2628
    #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2629
#endif
2630
2631
#ifdef HAVE_OPENAT
2632
12.8k
    #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2633
#else
2634
    #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2635
#endif
2636
2637
#ifdef HAVE_READLINKAT
2638
1
    #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2639
#else
2640
    #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2641
#endif
2642
2643
#ifdef HAVE_SYMLINKAT
2644
2
    #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2645
#else
2646
    #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2647
#endif
2648
2649
#ifdef HAVE_UNLINKAT
2650
36.9k
    #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2651
#else
2652
    #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2653
#endif
2654
2655
#ifdef HAVE_FCHDIR
2656
    #define PATH_HAVE_FCHDIR 1
2657
#else
2658
    #define PATH_HAVE_FCHDIR 0
2659
#endif
2660
2661
#ifdef HAVE_FCHMOD
2662
    #define PATH_HAVE_FCHMOD 1
2663
#else
2664
    #define PATH_HAVE_FCHMOD 0
2665
#endif
2666
2667
#ifdef HAVE_FCHOWN
2668
    #define PATH_HAVE_FCHOWN 1
2669
#else
2670
    #define PATH_HAVE_FCHOWN 0
2671
#endif
2672
2673
#ifdef HAVE_FDOPENDIR
2674
    #define PATH_HAVE_FDOPENDIR 1
2675
#else
2676
    #define PATH_HAVE_FDOPENDIR 0
2677
#endif
2678
2679
#ifdef HAVE_FEXECVE
2680
    #define PATH_HAVE_FEXECVE 1
2681
#else
2682
    #define PATH_HAVE_FEXECVE 0
2683
#endif
2684
2685
#ifdef HAVE_FPATHCONF
2686
    #define PATH_HAVE_FPATHCONF 1
2687
#else
2688
    #define PATH_HAVE_FPATHCONF 0
2689
#endif
2690
2691
#ifdef HAVE_FSTATVFS
2692
    #define PATH_HAVE_FSTATVFS 1
2693
#else
2694
    #define PATH_HAVE_FSTATVFS 0
2695
#endif
2696
2697
#ifdef HAVE_FTRUNCATE
2698
    #define PATH_HAVE_FTRUNCATE 1
2699
#else
2700
    #define PATH_HAVE_FTRUNCATE 0
2701
#endif
2702
/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
2703
2704
#ifdef MS_WINDOWS
2705
    #undef PATH_HAVE_FTRUNCATE
2706
    #define PATH_HAVE_FTRUNCATE 1
2707
#endif
2708
2709
/*[python input]
2710
2711
class path_t_converter(CConverter):
2712
2713
    type = "path_t"
2714
    impl_by_reference = True
2715
    parse_by_reference = True
2716
2717
    converter = 'path_converter'
2718
2719
    def converter_init(self, *, allow_fd=False, nullable=False):
2720
        # right now path_t doesn't support default values.
2721
        # to support a default value, you'll need to override initialize().
2722
        if self.default not in (unspecified, None):
2723
            fail("Can't specify a default to the path_t converter!")
2724
2725
        if self.c_default not in (None, 'Py_None'):
2726
            raise RuntimeError("Can't specify a c_default to the path_t converter!")
2727
2728
        self.nullable = nullable
2729
        self.allow_fd = allow_fd
2730
2731
    def pre_render(self):
2732
        def strify(value):
2733
            if isinstance(value, str):
2734
                return value
2735
            return str(int(bool(value)))
2736
2737
        # add self.py_name here when merging with posixmodule conversion
2738
        self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
2739
            self.function.name,
2740
            self.name,
2741
            strify(self.nullable),
2742
            strify(self.allow_fd),
2743
            )
2744
2745
    def cleanup(self):
2746
        return "path_cleanup(&" + self.name + ");\n"
2747
2748
2749
class dir_fd_converter(CConverter):
2750
    type = 'int'
2751
2752
    def converter_init(self, requires=None):
2753
        if self.default in (unspecified, None):
2754
            self.c_default = 'DEFAULT_DIR_FD'
2755
        if isinstance(requires, str):
2756
            self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2757
        else:
2758
            self.converter = 'dir_fd_converter'
2759
2760
class uid_t_converter(CConverter):
2761
    type = "uid_t"
2762
    converter = '_Py_Uid_Converter'
2763
2764
class gid_t_converter(CConverter):
2765
    type = "gid_t"
2766
    converter = '_Py_Gid_Converter'
2767
2768
class dev_t_converter(CConverter):
2769
    type = 'dev_t'
2770
    converter = '_Py_Dev_Converter'
2771
2772
class dev_t_return_converter(unsigned_long_return_converter):
2773
    type = 'dev_t'
2774
    conversion_fn = '_PyLong_FromDev'
2775
    unsigned_cast = '(dev_t)'
2776
2777
class FSConverter_converter(CConverter):
2778
    type = 'PyObject *'
2779
    converter = 'PyUnicode_FSConverter'
2780
    def converter_init(self):
2781
        if self.default is not unspecified:
2782
            fail("FSConverter_converter does not support default values")
2783
        self.c_default = 'NULL'
2784
2785
    def cleanup(self):
2786
        return "Py_XDECREF(" + self.name + ");\n"
2787
2788
class pid_t_converter(CConverter):
2789
    type = 'pid_t'
2790
    format_unit = '" _Py_PARSE_PID "'
2791
2792
class idtype_t_converter(int_converter):
2793
    type = 'idtype_t'
2794
2795
class id_t_converter(CConverter):
2796
    type = 'id_t'
2797
    format_unit = '" _Py_PARSE_PID "'
2798
2799
class intptr_t_converter(CConverter):
2800
    type = 'intptr_t'
2801
    format_unit = '" _Py_PARSE_INTPTR "'
2802
2803
class Py_off_t_converter(CConverter):
2804
    type = 'Py_off_t'
2805
    converter = 'Py_off_t_converter'
2806
2807
class Py_off_t_return_converter(long_return_converter):
2808
    type = 'Py_off_t'
2809
    conversion_fn = 'PyLong_FromPy_off_t'
2810
2811
class path_confname_converter(CConverter):
2812
    type="int"
2813
    converter="conv_path_confname"
2814
2815
class confstr_confname_converter(path_confname_converter):
2816
    converter='conv_confstr_confname'
2817
2818
class sysconf_confname_converter(path_confname_converter):
2819
    converter="conv_sysconf_confname"
2820
2821
[python start generated code]*/
2822
/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/
2823
2824
/*[clinic input]
2825
2826
os.stat
2827
2828
    path : path_t(allow_fd=True)
2829
        Path to be examined; can be string, bytes, a path-like object or
2830
        open-file-descriptor int.
2831
2832
    *
2833
2834
    dir_fd : dir_fd(requires='fstatat') = None
2835
        If not None, it should be a file descriptor open to a directory,
2836
        and path should be a relative string; path will then be relative to
2837
        that directory.
2838
2839
    follow_symlinks: bool = True
2840
        If False, and the last element of the path is a symbolic link,
2841
        stat will examine the symbolic link itself instead of the file
2842
        the link points to.
2843
2844
Perform a stat system call on the given path.
2845
2846
dir_fd and follow_symlinks may not be implemented
2847
  on your platform.  If they are unavailable, using them will raise a
2848
  NotImplementedError.
2849
2850
It's an error to use dir_fd or follow_symlinks when specifying path as
2851
  an open file descriptor.
2852
2853
[clinic start generated code]*/
2854
2855
static PyObject *
2856
os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2857
/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
2858
354k
{
2859
354k
    return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
2860
354k
}
2861
2862
2863
/*[clinic input]
2864
os.lstat
2865
2866
    path : path_t
2867
2868
    *
2869
2870
    dir_fd : dir_fd(requires='fstatat') = None
2871
2872
Perform a stat system call on the given path, without following symbolic links.
2873
2874
Like stat(), but do not follow symbolic links.
2875
Equivalent to stat(path, follow_symlinks=False).
2876
[clinic start generated code]*/
2877
2878
static PyObject *
2879
os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2880
/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
2881
43.7k
{
2882
43.7k
    int follow_symlinks = 0;
2883
43.7k
    return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
2884
43.7k
}
2885
2886
2887
/*[clinic input]
2888
os.access -> bool
2889
2890
    path: path_t
2891
        Path to be tested; can be string, bytes, or a path-like object.
2892
2893
    mode: int
2894
        Operating-system mode bitfield.  Can be F_OK to test existence,
2895
        or the inclusive-OR of R_OK, W_OK, and X_OK.
2896
2897
    *
2898
2899
    dir_fd : dir_fd(requires='faccessat') = None
2900
        If not None, it should be a file descriptor open to a directory,
2901
        and path should be relative; path will then be relative to that
2902
        directory.
2903
2904
    effective_ids: bool = False
2905
        If True, access will use the effective uid/gid instead of
2906
        the real uid/gid.
2907
2908
    follow_symlinks: bool = True
2909
        If False, and the last element of the path is a symbolic link,
2910
        access will examine the symbolic link itself instead of the file
2911
        the link points to.
2912
2913
Use the real uid/gid to test for access to a path.
2914
2915
{parameters}
2916
dir_fd, effective_ids, and follow_symlinks may not be implemented
2917
  on your platform.  If they are unavailable, using them will raise a
2918
  NotImplementedError.
2919
2920
Note that most operations will use the effective uid/gid, therefore this
2921
  routine can be used in a suid/sgid environment to test if the invoking user
2922
  has the specified access to the path.
2923
2924
[clinic start generated code]*/
2925
2926
static int
2927
os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
2928
               int effective_ids, int follow_symlinks)
2929
/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
2930
140
{
2931
140
    int return_value;
2932
2933
#ifdef MS_WINDOWS
2934
    DWORD attr;
2935
#else
2936
140
    int result;
2937
140
#endif
2938
2939
140
#ifdef HAVE_FACCESSAT
2940
140
    int faccessat_unavailable = 0;
2941
140
#endif
2942
2943
#ifndef HAVE_FACCESSAT
2944
    if (follow_symlinks_specified("access", follow_symlinks))
2945
        return -1;
2946
2947
    if (effective_ids) {
2948
        argument_unavailable_error("access", "effective_ids");
2949
        return -1;
2950
    }
2951
#endif
2952
2953
#ifdef MS_WINDOWS
2954
    Py_BEGIN_ALLOW_THREADS
2955
    attr = GetFileAttributesW(path->wide);
2956
    Py_END_ALLOW_THREADS
2957
2958
    /*
2959
     * Access is possible if
2960
     *   * we didn't get a -1, and
2961
     *     * write access wasn't requested,
2962
     *     * or the file isn't read-only,
2963
     *     * or it's a directory.
2964
     * (Directories cannot be read-only on Windows.)
2965
    */
2966
    return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
2967
            (!(mode & 2) ||
2968
            !(attr & FILE_ATTRIBUTE_READONLY) ||
2969
            (attr & FILE_ATTRIBUTE_DIRECTORY));
2970
#else
2971
2972
140
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
140
#define Py_BEGIN_ALLOW_THREADS { \
143
140
                        PyThreadState *_save; \
144
140
                        _save = PyEval_SaveThread();
2973
140
#ifdef HAVE_FACCESSAT
2974
140
    if ((dir_fd != DEFAULT_DIR_FD) ||
Line
Count
Source
904
140
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (2974:9): [True: 1, False: 139]
2975
140
        effective_ids ||
  Branch (2975:9): [True: 4, False: 135]
2976
140
        !follow_symlinks) {
  Branch (2976:9): [True: 0, False: 135]
2977
2978
5
        if (HAVE_FACCESSAT_RUNTIME) {
Line
Count
Source
164
5
#  define HAVE_FACCESSAT_RUNTIME 1
  Branch (164:34): [Folded - Ignored]
2979
5
            int flags = 0;
2980
5
            if (!follow_symlinks)
  Branch (2980:17): [True: 0, False: 5]
2981
0
                flags |= AT_SYMLINK_NOFOLLOW;
2982
5
            if (effective_ids)
  Branch (2982:17): [True: 4, False: 1]
2983
4
                flags |= AT_EACCESS;
2984
5
            result = faccessat(dir_fd, path->narrow, mode, flags);
2985
5
        } else {
2986
0
            faccessat_unavailable = 1;
2987
0
        }
2988
5
    }
2989
135
    else
2990
135
#endif
2991
135
        result = access(path->narrow, mode);
2992
140
    Py_END_ALLOW_THREADS
Line
Count
Source
147
140
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
140
                 }
2993
2994
140
#ifdef HAVE_FACCESSAT
2995
140
    if (faccessat_unavailable) {
  Branch (2995:9): [True: 0, False: 140]
2996
0
        if (dir_fd != DEFAULT_DIR_FD) {
Line
Count
Source
904
0
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (2996:13): [True: 0, False: 0]
2997
0
            argument_unavailable_error("access", "dir_fd");
2998
0
            return -1;
2999
0
        }
3000
0
        if (follow_symlinks_specified("access", follow_symlinks))
  Branch (3000:13): [True: 0, False: 0]
3001
0
            return -1;
3002
3003
0
        if (effective_ids) {
  Branch (3003:13): [True: 0, False: 0]
3004
0
            argument_unavailable_error("access", "effective_ids");
3005
0
            return -1;
3006
0
        }
3007
        /* should be unreachable */
3008
0
        return -1;
3009
0
    }
3010
140
#endif
3011
140
    return_value = !result;
3012
140
#endif
3013
3014
140
    return return_value;
3015
140
}
3016
3017
#ifndef F_OK
3018
#define F_OK 0
3019
#endif
3020
#ifndef R_OK
3021
#define R_OK 4
3022
#endif
3023
#ifndef W_OK
3024
#define W_OK 2
3025
#endif
3026
#ifndef X_OK
3027
#define X_OK 1
3028
#endif
3029
3030
3031
#ifdef HAVE_TTYNAME
3032
/*[clinic input]
3033
os.ttyname
3034
3035
    fd: int
3036
        Integer file descriptor handle.
3037
3038
    /
3039
3040
Return the name of the terminal device connected to 'fd'.
3041
[clinic start generated code]*/
3042
3043
static PyObject *
3044
os_ttyname_impl(PyObject *module, int fd)
3045
/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
3046
1
{
3047
3048
1
    long size = sysconf(_SC_TTY_NAME_MAX);
3049
1
    if (size == -1) {
  Branch (3049:9): [True: 0, False: 1]
3050
0
        return posix_error();
3051
0
    }
3052
1
    char *buffer = (char *)PyMem_RawMalloc(size);
3053
1
    if (buffer == NULL) {
  Branch (3053:9): [True: 0, False: 1]
3054
0
        return PyErr_NoMemory();
3055
0
    }
3056
1
    int ret = ttyname_r(fd, buffer, size);
3057
1
    if (ret != 0) {
  Branch (3057:9): [True: 1, False: 0]
3058
1
        PyMem_RawFree(buffer);
3059
1
        errno = ret;
3060
1
        return posix_error();
3061
1
    }
3062
0
    PyObject *res = PyUnicode_DecodeFSDefault(buffer);
3063
0
    PyMem_RawFree(buffer);
3064
0
    return res;
3065
1
}
3066
#endif
3067
3068
#ifdef HAVE_CTERMID
3069
/*[clinic input]
3070
os.ctermid
3071
3072
Return the name of the controlling terminal for this process.
3073
[clinic start generated code]*/
3074
3075
static PyObject *
3076
os_ctermid_impl(PyObject *module)
3077
/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
3078
1
{
3079
1
    char *ret;
3080
1
    char buffer[L_ctermid];
3081
3082
#ifdef USE_CTERMID_R
3083
    ret = ctermid_r(buffer);
3084
#else
3085
1
    ret = ctermid(buffer);
3086
1
#endif
3087
1
    if (ret == NULL)
  Branch (3087:9): [True: 0, False: 1]
3088
0
        return posix_error();
3089
1
    return PyUnicode_DecodeFSDefault(buffer);
3090
1
}
3091
#endif /* HAVE_CTERMID */
3092
3093
3094
/*[clinic input]
3095
os.chdir
3096
3097
    path: path_t(allow_fd='PATH_HAVE_FCHDIR')
3098
3099
Change the current working directory to the specified path.
3100
3101
path may always be specified as a string.
3102
On some platforms, path may also be specified as an open file descriptor.
3103
  If this functionality is unavailable, using it raises an exception.
3104
[clinic start generated code]*/
3105
3106
static PyObject *
3107
os_chdir_impl(PyObject *module, path_t *path)
3108
/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
3109
1.53k
{
3110
1.53k
    int result;
3111
3112
1.53k
    if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
  Branch (3112:9): [True: 0, False: 1.53k]
3113
0
        return NULL;
3114
0
    }
3115
3116
1.53k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
1.53k
#define Py_BEGIN_ALLOW_THREADS { \
143
1.53k
                        PyThreadState *_save; \
144
1.53k
                        _save = PyEval_SaveThread();
3117
#ifdef MS_WINDOWS
3118
    /* on unix, success = 0, on windows, success = !0 */
3119
    result = !win32_wchdir(path->wide);
3120
#else
3121
1.53k
#ifdef HAVE_FCHDIR
3122
1.53k
    if (path->fd != -1)
  Branch (3122:9): [True: 0, False: 1.53k]
3123
0
        result = fchdir(path->fd);
3124
1.53k
    else
3125
1.53k
#endif
3126
1.53k
        result = chdir(path->narrow);
3127
1.53k
#endif
3128
1.53k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
1.53k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
1.53k
                 }
3129
3130
1.53k
    if (result) {
  Branch (3130:9): [True: 190, False: 1.34k]
3131
190
        return path_error(path);
3132
190
    }
3133
3134
1.53k
    Py_RETURN_NONE;
Line
Count
Source
661
1.34k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1.34k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1.34k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1.34k
#  define _Py_CAST(type, expr) ((type)(expr))
3135
1.53k
}
3136
3137
3138
#ifdef HAVE_FCHDIR
3139
/*[clinic input]
3140
os.fchdir
3141
3142
    fd: fildes
3143
3144
Change to the directory of the given file descriptor.
3145
3146
fd must be opened on a directory, not a file.
3147
Equivalent to os.chdir(fd).
3148
3149
[clinic start generated code]*/
3150
3151
static PyObject *
3152
os_fchdir_impl(PyObject *module, int fd)
3153
/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
3154
1
{
3155
1
    if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
  Branch (3155:9): [True: 0, False: 1]
3156
0
        return NULL;
3157
0
    }
3158
1
    return posix_fildes_fd(fd, fchdir);
3159
1
}
3160
#endif /* HAVE_FCHDIR */
3161
3162
3163
/*[clinic input]
3164
os.chmod
3165
3166
    path: path_t(allow_fd='PATH_HAVE_FCHMOD')
3167
        Path to be modified.  May always be specified as a str, bytes, or a path-like object.
3168
        On some platforms, path may also be specified as an open file descriptor.
3169
        If this functionality is unavailable, using it raises an exception.
3170
3171
    mode: int
3172
        Operating-system mode bitfield.
3173
3174
    *
3175
3176
    dir_fd : dir_fd(requires='fchmodat') = None
3177
        If not None, it should be a file descriptor open to a directory,
3178
        and path should be relative; path will then be relative to that
3179
        directory.
3180
3181
    follow_symlinks: bool = True
3182
        If False, and the last element of the path is a symbolic link,
3183
        chmod will modify the symbolic link itself instead of the file
3184
        the link points to.
3185
3186
Change the access permissions of a file.
3187
3188
It is an error to use dir_fd or follow_symlinks when specifying path as
3189
  an open file descriptor.
3190
dir_fd and follow_symlinks may not be implemented on your platform.
3191
  If they are unavailable, using them will raise a NotImplementedError.
3192
3193
[clinic start generated code]*/
3194
3195
static PyObject *
3196
os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
3197
              int follow_symlinks)
3198
/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
3199
11.5k
{
3200
11.5k
    int result;
3201
3202
#ifdef MS_WINDOWS
3203
    DWORD attr;
3204
#endif
3205
3206
11.5k
#ifdef HAVE_FCHMODAT
3207
11.5k
    int fchmodat_nofollow_unsupported = 0;
3208
11.5k
    int fchmodat_unsupported = 0;
3209
11.5k
#endif
3210
3211
#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3212
    if (follow_symlinks_specified("chmod", follow_symlinks))
3213
        return NULL;
3214
#endif
3215
3216
11.5k
    if (PySys_Audit("os.chmod", "Oii", path->object, mode,
  Branch (3216:9): [True: 0, False: 11.5k]
3217
11.5k
                    dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
Line
Count
Source
904
11.5k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3217:21): [True: 11.5k, False: 1]
3218
0
        return NULL;
3219
0
    }
3220
3221
#ifdef MS_WINDOWS
3222
    Py_BEGIN_ALLOW_THREADS
3223
    attr = GetFileAttributesW(path->wide);
3224
    if (attr == INVALID_FILE_ATTRIBUTES)
3225
        result = 0;
3226
    else {
3227
        if (mode & _S_IWRITE)
3228
            attr &= ~FILE_ATTRIBUTE_READONLY;
3229
        else
3230
            attr |= FILE_ATTRIBUTE_READONLY;
3231
        result = SetFileAttributesW(path->wide, attr);
3232
    }
3233
    Py_END_ALLOW_THREADS
3234
3235
    if (!result) {
3236
        return path_error(path);
3237
    }
3238
#else /* MS_WINDOWS */
3239
11.5k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
11.5k
#define Py_BEGIN_ALLOW_THREADS { \
143
11.5k
                        PyThreadState *_save; \
144
11.5k
                        _save = PyEval_SaveThread();
3240
11.5k
#ifdef HAVE_FCHMOD
3241
11.5k
    if (path->fd != -1)
  Branch (3241:9): [True: 0, False: 11.5k]
3242
0
        result = fchmod(path->fd, mode);
3243
11.5k
    else
3244
11.5k
#endif /* HAVE_CHMOD */
3245
#ifdef HAVE_LCHMOD
3246
    if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3247
        result = lchmod(path->narrow, mode);
3248
    else
3249
#endif /* HAVE_LCHMOD */
3250
11.5k
#ifdef HAVE_FCHMODAT
3251
11.5k
    if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
Line
Count
Source
904
11.5k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3251:9): [True: 1, False: 11.5k]
  Branch (3251:39): [True: 0, False: 11.5k]
3252
1
        if (HAVE_FCHMODAT_RUNTIME) {
Line
Count
Source
165
1
#  define HAVE_FCHMODAT_RUNTIME 1
  Branch (165:33): [Folded - Ignored]
3253
            /*
3254
             * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3255
             * The documentation specifically shows how to use it,
3256
             * and then says it isn't implemented yet.
3257
             * (true on linux with glibc 2.15, and openindiana 3.x)
3258
             *
3259
             * Once it is supported, os.chmod will automatically
3260
             * support dir_fd and follow_symlinks=False.  (Hopefully.)
3261
             * Until then, we need to be careful what exception we raise.
3262
             */
3263
1
            result = fchmodat(dir_fd, path->narrow, mode,
3264
1
                              follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
  Branch (3264:31): [True: 1, False: 0]
3265
            /*
3266
             * But wait!  We can't throw the exception without allowing threads,
3267
             * and we can't do that in this nested scope.  (Macro trickery, sigh.)
3268
             */
3269
1
            fchmodat_nofollow_unsupported =
3270
1
                             result &&
  Branch (3270:30): [True: 0, False: 1]
3271
1
                             ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
  Branch (3271:31): [True: 0, False: 0]
  Branch (3271:53): [True: 0, False: 0]
3272
1
                             !follow_symlinks;
  Branch (3272:30): [True: 0, False: 0]
3273
1
        } else {
3274
0
            fchmodat_unsupported = 1;
3275
0
            fchmodat_nofollow_unsupported = 1;
3276
3277
0
            result = -1;
3278
0
        }
3279
1
    }
3280
11.5k
    else
3281
11.5k
#endif /* HAVE_FHCMODAT */
3282
11.5k
    {
3283
11.5k
#ifdef HAVE_CHMOD
3284
11.5k
        result = chmod(path->narrow, mode);
3285
#elif defined(__wasi__)
3286
        // WASI SDK 15.0 does not support chmod.
3287
        // Ignore missing syscall for now.
3288
        result = 0;
3289
#else
3290
        result = -1;
3291
        errno = ENOSYS;
3292
#endif
3293
11.5k
    }
3294
11.5k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
11.5k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
11.5k
                 }
3295
3296
11.5k
    if (result) {
  Branch (3296:9): [True: 5, False: 11.5k]
3297
5
#ifdef HAVE_FCHMODAT
3298
5
        if (fchmodat_unsupported) {
  Branch (3298:13): [True: 0, False: 5]
3299
0
            if (dir_fd != DEFAULT_DIR_FD) {
Line
Count
Source
904
0
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3299:17): [True: 0, False: 0]
3300
0
                argument_unavailable_error("chmod", "dir_fd");
3301
0
                return NULL;
3302
0
            }
3303
0
        }
3304
3305
5
        if (fchmodat_nofollow_unsupported) {
  Branch (3305:13): [True: 0, False: 5]
3306
0
            if (dir_fd != DEFAULT_DIR_FD)
Line
Count
Source
904
0
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3306:17): [True: 0, False: 0]
3307
0
                dir_fd_and_follow_symlinks_invalid("chmod",
3308
0
                                                   dir_fd, follow_symlinks);
3309
0
            else
3310
0
                follow_symlinks_specified("chmod", follow_symlinks);
3311
0
            return NULL;
3312
0
        }
3313
5
        else
3314
5
#endif /* HAVE_FCHMODAT */
3315
5
        return path_error(path);
3316
5
    }
3317
11.5k
#endif /* MS_WINDOWS */
3318
3319
11.5k
    Py_RETURN_NONE;
Line
Count
Source
661
11.5k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
11.5k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
11.5k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
11.5k
#  define _Py_CAST(type, expr) ((type)(expr))
3320
11.5k
}
3321
3322
3323
#ifdef HAVE_FCHMOD
3324
/*[clinic input]
3325
os.fchmod
3326
3327
    fd: int
3328
    mode: int
3329
3330
Change the access permissions of the file given by file descriptor fd.
3331
3332
Equivalent to os.chmod(fd, mode).
3333
[clinic start generated code]*/
3334
3335
static PyObject *
3336
os_fchmod_impl(PyObject *module, int fd, int mode)
3337
/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
3338
1
{
3339
1
    int res;
3340
1
    int async_err = 0;
3341
3342
1
    if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
  Branch (3342:9): [True: 0, False: 1]
3343
0
        return NULL;
3344
0
    }
3345
3346
1
    do {
3347
1
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
1
#define Py_BEGIN_ALLOW_THREADS { \
143
1
                        PyThreadState *_save; \
144
1
                        _save = PyEval_SaveThread();
3348
1
        res = fchmod(fd, mode);
3349
1
        Py_END_ALLOW_THREADS
Line
Count
Source
147
1
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
1
                 }
3350
1
    } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (3350:14): [True: 1, False: 0]
  Branch (3350:26): [True: 0, False: 1]
  Branch (3350:44): [True: 0, False: 0]
3351
1
    if (res != 0)
  Branch (3351:9): [True: 1, False: 0]
3352
1
        return (!async_err) ? posix_error() : NULL;
  Branch (3352:16): [True: 1, False: 0]
3353
3354
1
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
3355
1
}
3356
#endif /* HAVE_FCHMOD */
3357
3358
3359
#ifdef HAVE_LCHMOD
3360
/*[clinic input]
3361
os.lchmod
3362
3363
    path: path_t
3364
    mode: int
3365
3366
Change the access permissions of a file, without following symbolic links.
3367
3368
If path is a symlink, this affects the link itself rather than the target.
3369
Equivalent to chmod(path, mode, follow_symlinks=False)."
3370
[clinic start generated code]*/
3371
3372
static PyObject *
3373
os_lchmod_impl(PyObject *module, path_t *path, int mode)
3374
/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
3375
{
3376
    int res;
3377
    if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3378
        return NULL;
3379
    }
3380
    Py_BEGIN_ALLOW_THREADS
3381
    res = lchmod(path->narrow, mode);
3382
    Py_END_ALLOW_THREADS
3383
    if (res < 0) {
3384
        path_error(path);
3385
        return NULL;
3386
    }
3387
    Py_RETURN_NONE;
3388
}
3389
#endif /* HAVE_LCHMOD */
3390
3391
3392
#ifdef HAVE_CHFLAGS
3393
/*[clinic input]
3394
os.chflags
3395
3396
    path: path_t
3397
    flags: unsigned_long(bitwise=True)
3398
    follow_symlinks: bool=True
3399
3400
Set file flags.
3401
3402
If follow_symlinks is False, and the last element of the path is a symbolic
3403
  link, chflags will change flags on the symbolic link itself instead of the
3404
  file the link points to.
3405
follow_symlinks may not be implemented on your platform.  If it is
3406
unavailable, using it will raise a NotImplementedError.
3407
3408
[clinic start generated code]*/
3409
3410
static PyObject *
3411
os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
3412
                int follow_symlinks)
3413
/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
3414
{
3415
    int result;
3416
3417
#ifndef HAVE_LCHFLAGS
3418
    if (follow_symlinks_specified("chflags", follow_symlinks))
3419
        return NULL;
3420
#endif
3421
3422
    if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3423
        return NULL;
3424
    }
3425
3426
    Py_BEGIN_ALLOW_THREADS
3427
#ifdef HAVE_LCHFLAGS
3428
    if (!follow_symlinks)
3429
        result = lchflags(path->narrow, flags);
3430
    else
3431
#endif
3432
        result = chflags(path->narrow, flags);
3433
    Py_END_ALLOW_THREADS
3434
3435
    if (result)
3436
        return path_error(path);
3437
3438
    Py_RETURN_NONE;
3439
}
3440
#endif /* HAVE_CHFLAGS */
3441
3442
3443
#ifdef HAVE_LCHFLAGS
3444
/*[clinic input]
3445
os.lchflags
3446
3447
    path: path_t
3448
    flags: unsigned_long(bitwise=True)
3449
3450
Set file flags.
3451
3452
This function will not follow symbolic links.
3453
Equivalent to chflags(path, flags, follow_symlinks=False).
3454
[clinic start generated code]*/
3455
3456
static PyObject *
3457
os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3458
/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
3459
{
3460
    int res;
3461
    if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3462
        return NULL;
3463
    }
3464
    Py_BEGIN_ALLOW_THREADS
3465
    res = lchflags(path->narrow, flags);
3466
    Py_END_ALLOW_THREADS
3467
    if (res < 0) {
3468
        return path_error(path);
3469
    }
3470
    Py_RETURN_NONE;
3471
}
3472
#endif /* HAVE_LCHFLAGS */
3473
3474
3475
#ifdef HAVE_CHROOT
3476
/*[clinic input]
3477
os.chroot
3478
    path: path_t
3479
3480
Change root directory to path.
3481
3482
[clinic start generated code]*/
3483
3484
static PyObject *
3485
os_chroot_impl(PyObject *module, path_t *path)
3486
/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
3487
5
{
3488
5
    int res;
3489
5
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
5
#define Py_BEGIN_ALLOW_THREADS { \
143
5
                        PyThreadState *_save; \
144
5
                        _save = PyEval_SaveThread();
3490
5
    res = chroot(path->narrow);
3491
5
    Py_END_ALLOW_THREADS
Line
Count
Source
147
5
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
5
                 }
3492
5
    if (res < 0)
  Branch (3492:9): [True: 5, False: 0]
3493
5
        return path_error(path);
3494
5
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
3495
5
}
3496
#endif /* HAVE_CHROOT */
3497
3498
3499
#ifdef HAVE_FSYNC
3500
/*[clinic input]
3501
os.fsync
3502
3503
    fd: fildes
3504
3505
Force write of fd to disk.
3506
[clinic start generated code]*/
3507
3508
static PyObject *
3509
os_fsync_impl(PyObject *module, int fd)
3510
/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
3511
543
{
3512
543
    return posix_fildes_fd(fd, fsync);
3513
543
}
3514
#endif /* HAVE_FSYNC */
3515
3516
3517
#ifdef HAVE_SYNC
3518
/*[clinic input]
3519
os.sync
3520
3521
Force write of everything to disk.
3522
[clinic start generated code]*/
3523
3524
static PyObject *
3525
os_sync_impl(PyObject *module)
3526
/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
3527
1
{
3528
1
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
1
#define Py_BEGIN_ALLOW_THREADS { \
143
1
                        PyThreadState *_save; \
144
1
                        _save = PyEval_SaveThread();
3529
1
    sync();
3530
1
    Py_END_ALLOW_THREADS
Line
Count
Source
147
1
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
1
                 }
3531
1
    Py_RETURN_NONE;
Line
Count
Source
661
1
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
3532
1
}
3533
#endif /* HAVE_SYNC */
3534
3535
3536
#ifdef HAVE_FDATASYNC
3537
#ifdef __hpux
3538
extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3539
#endif
3540
3541
/*[clinic input]
3542
os.fdatasync
3543
3544
    fd: fildes
3545
3546
Force write of fd to disk without forcing update of metadata.
3547
[clinic start generated code]*/
3548
3549
static PyObject *
3550
os_fdatasync_impl(PyObject *module, int fd)
3551
/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
3552
1
{
3553
1
    return posix_fildes_fd(fd, fdatasync);
3554
1
}
3555
#endif /* HAVE_FDATASYNC */
3556
3557
3558
#ifdef HAVE_CHOWN
3559
/*[clinic input]
3560
os.chown
3561
3562
    path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3563
        Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
3564
3565
    uid: uid_t
3566
3567
    gid: gid_t
3568
3569
    *
3570
3571
    dir_fd : dir_fd(requires='fchownat') = None
3572
        If not None, it should be a file descriptor open to a directory,
3573
        and path should be relative; path will then be relative to that
3574
        directory.
3575
3576
    follow_symlinks: bool = True
3577
        If False, and the last element of the path is a symbolic link,
3578
        stat will examine the symbolic link itself instead of the file
3579
        the link points to.
3580
3581
Change the owner and group id of path to the numeric uid and gid.\
3582
3583
path may always be specified as a string.
3584
On some platforms, path may also be specified as an open file descriptor.
3585
  If this functionality is unavailable, using it raises an exception.
3586
If dir_fd is not None, it should be a file descriptor open to a directory,
3587
  and path should be relative; path will then be relative to that directory.
3588
If follow_symlinks is False, and the last element of the path is a symbolic
3589
  link, chown will modify the symbolic link itself instead of the file the
3590
  link points to.
3591
It is an error to use dir_fd or follow_symlinks when specifying path as
3592
  an open file descriptor.
3593
dir_fd and follow_symlinks may not be implemented on your platform.
3594
  If they are unavailable, using them will raise a NotImplementedError.
3595
3596
[clinic start generated code]*/
3597
3598
static PyObject *
3599
os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
3600
              int dir_fd, int follow_symlinks)
3601
/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
3602
28
{
3603
28
    int result;
3604
3605
28
#if defined(HAVE_FCHOWNAT)
3606
28
    int fchownat_unsupported = 0;
3607
28
#endif
3608
3609
#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3610
    if (follow_symlinks_specified("chown", follow_symlinks))
3611
        return NULL;
3612
#endif
3613
28
    if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
  Branch (3613:9): [True: 0, False: 28]
3614
28
        fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
  Branch (3614:9): [True: 0, False: 28]
3615
0
        return NULL;
3616
3617
28
    if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
  Branch (3617:9): [True: 0, False: 28]
3618
28
                    dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
Line
Count
Source
904
28
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3618:21): [True: 27, False: 1]
3619
0
        return NULL;
3620
0
    }
3621
3622
28
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
28
#define Py_BEGIN_ALLOW_THREADS { \
143
28
                        PyThreadState *_save; \
144
28
                        _save = PyEval_SaveThread();
3623
28
#ifdef HAVE_FCHOWN
3624
28
    if (path->fd != -1)
  Branch (3624:9): [True: 0, False: 28]
3625
0
        result = fchown(path->fd, uid, gid);
3626
28
    else
3627
28
#endif
3628
28
#ifdef HAVE_LCHOWN
3629
28
    if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Line
Count
Source
904
0
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3629:9): [True: 0, False: 28]
  Branch (3629:31): [True: 0, False: 0]
3630
0
        result = lchown(path->narrow, uid, gid);
3631
28
    else
3632
28
#endif
3633
28
#ifdef HAVE_FCHOWNAT
3634
28
    if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
Line
Count
Source
904
28
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3634:9): [True: 1, False: 27]
  Branch (3634:39): [True: 0, False: 27]
3635
1
      if (HAVE_FCHOWNAT_RUNTIME) {
Line
Count
Source
166
1
#  define HAVE_FCHOWNAT_RUNTIME 1
  Branch (166:33): [Folded - Ignored]
3636
1
        result = fchownat(dir_fd, path->narrow, uid, gid,
3637
1
                          follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
  Branch (3637:27): [True: 1, False: 0]
3638
1
      } else {
3639
0
         fchownat_unsupported = 1;
3640
0
      }
3641
1
    } else
3642
27
#endif
3643
27
        result = chown(path->narrow, uid, gid);
3644
28
    Py_END_ALLOW_THREADS
Line
Count
Source
147
28
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
28
                 }
3645
3646
28
#ifdef HAVE_FCHOWNAT
3647
28
    if (fchownat_unsupported) {
  Branch (3647:9): [True: 0, False: 28]
3648
        /* This would be incorrect if the current platform
3649
         * doesn't support lchown.
3650
         */
3651
0
        argument_unavailable_error(NULL, "dir_fd");
3652
0
        return NULL;
3653
0
    }
3654
28
#endif
3655
3656
28
    if (result)
  Branch (3656:9): [True: 10, False: 18]
3657
10
        return path_error(path);
3658
3659
28
    Py_RETURN_NONE;
Line
Count
Source
661
18
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
18
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
18
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
18
#  define _Py_CAST(type, expr) ((type)(expr))
3660
28
}
3661
#endif /* HAVE_CHOWN */
3662
3663
3664
#ifdef HAVE_FCHOWN
3665
/*[clinic input]
3666
os.fchown
3667
3668
    fd: int
3669
    uid: uid_t
3670
    gid: gid_t
3671
3672
Change the owner and group id of the file specified by file descriptor.
3673
3674
Equivalent to os.chown(fd, uid, gid).
3675
3676
[clinic start generated code]*/
3677
3678
static PyObject *
3679
os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3680
/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
3681
7
{
3682
7
    int res;
3683
7
    int async_err = 0;
3684
3685
7
    if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
  Branch (3685:9): [True: 0, False: 7]
3686
0
        return NULL;
3687
0
    }
3688
3689
7
    do {
3690
7
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
7
#define Py_BEGIN_ALLOW_THREADS { \
143
7
                        PyThreadState *_save; \
144
7
                        _save = PyEval_SaveThread();
3691
7
        res = fchown(fd, uid, gid);
3692
7
        Py_END_ALLOW_THREADS
Line
Count
Source
147
7
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
7
                 }
3693
7
    } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (3693:14): [True: 4, False: 3]
  Branch (3693:26): [True: 0, False: 4]
  Branch (3693:44): [True: 0, False: 0]
3694
7
    if (res != 0)
  Branch (3694:9): [True: 4, False: 3]
3695
4
        return (!async_err) ? posix_error() : NULL;
  Branch (3695:16): [True: 4, False: 0]
3696
3697
7
    Py_RETURN_NONE;
Line
Count
Source
661
3
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
3
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
3
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
3
#  define _Py_CAST(type, expr) ((type)(expr))
3698
7
}
3699
#endif /* HAVE_FCHOWN */
3700
3701
3702
#ifdef HAVE_LCHOWN
3703
/*[clinic input]
3704
os.lchown
3705
3706
    path : path_t
3707
    uid: uid_t
3708
    gid: gid_t
3709
3710
Change the owner and group id of path to the numeric uid and gid.
3711
3712
This function will not follow symbolic links.
3713
Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3714
[clinic start generated code]*/
3715
3716
static PyObject *
3717
os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3718
/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
3719
11
{
3720
11
    int res;
3721
11
    if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
  Branch (3721:9): [True: 0, False: 11]
3722
0
        return NULL;
3723
0
    }
3724
11
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
11
#define Py_BEGIN_ALLOW_THREADS { \
143
11
                        PyThreadState *_save; \
144
11
                        _save = PyEval_SaveThread();
3725
11
    res = lchown(path->narrow, uid, gid);
3726
11
    Py_END_ALLOW_THREADS
Line
Count
Source
147
11
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
11
                 }
3727
11
    if (res < 0) {
  Branch (3727:9): [True: 8, False: 3]
3728
8
        return path_error(path);
3729
8
    }
3730
11
    Py_RETURN_NONE;
Line
Count
Source
661
3
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
3
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
3
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
3
#  define _Py_CAST(type, expr) ((type)(expr))
3731
11
}
3732
#endif /* HAVE_LCHOWN */
3733
3734
3735
static PyObject *
3736
posix_getcwd(int use_bytes)
3737
6.79k
{
3738
#ifdef MS_WINDOWS
3739
    wchar_t wbuf[MAXPATHLEN];
3740
    wchar_t *wbuf2 = wbuf;
3741
    DWORD len;
3742
3743
    Py_BEGIN_ALLOW_THREADS
3744
    len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3745
    /* If the buffer is large enough, len does not include the
3746
       terminating \0. If the buffer is too small, len includes
3747
       the space needed for the terminator. */
3748
    if (len >= Py_ARRAY_LENGTH(wbuf)) {
3749
        if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
3750
            wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
3751
        }
3752
        else {
3753
            wbuf2 = NULL;
3754
        }
3755
        if (wbuf2) {
3756
            len = GetCurrentDirectoryW(len, wbuf2);
3757
        }
3758
    }
3759
    Py_END_ALLOW_THREADS
3760
3761
    if (!wbuf2) {
3762
        PyErr_NoMemory();
3763
        return NULL;
3764
    }
3765
    if (!len) {
3766
        if (wbuf2 != wbuf)
3767
            PyMem_RawFree(wbuf2);
3768
        return PyErr_SetFromWindowsErr(0);
3769
    }
3770
3771
    PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3772
    if (wbuf2 != wbuf) {
3773
        PyMem_RawFree(wbuf2);
3774
    }
3775
3776
    if (use_bytes) {
3777
        if (resobj == NULL) {
3778
            return NULL;
3779
        }
3780
        Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3781
    }
3782
3783
    return resobj;
3784
#else
3785
6.79k
    const size_t chunk = 1024;
3786
3787
6.79k
    char *buf = NULL;
3788
6.79k
    char *cwd = NULL;
3789
6.79k
    size_t buflen = 0;
3790
3791
6.79k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
6.79k
#define Py_BEGIN_ALLOW_THREADS { \
143
6.79k
                        PyThreadState *_save; \
144
6.79k
                        _save = PyEval_SaveThread();
3792
6.79k
    do {
3793
6.79k
        char *newbuf;
3794
6.79k
        if (buflen <= PY_SSIZE_T_MAX - chunk) {
Line
Count
Source
180
6.79k
#   define PY_SSIZE_T_MAX SSIZE_MAX
  Branch (3794:13): [True: 6.79k, False: 0]
3795
6.79k
            buflen += chunk;
3796
6.79k
            newbuf = PyMem_RawRealloc(buf, buflen);
3797
6.79k
        }
3798
0
        else {
3799
0
            newbuf = NULL;
3800
0
        }
3801
6.79k
        if (newbuf == NULL) {
  Branch (3801:13): [True: 0, False: 6.79k]
3802
0
            PyMem_RawFree(buf);
3803
0
            buf = NULL;
3804
0
            break;
3805
0
        }
3806
6.79k
        buf = newbuf;
3807
3808
6.79k
        cwd = getcwd(buf, buflen);
3809
6.79k
    } while (cwd == NULL && errno == ERANGE);
  Branch (3809:14): [True: 9, False: 6.78k]
  Branch (3809:29): [True: 5, False: 4]
3810
6.79k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
6.79k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
6.79k
                 }
3811
3812
6.79k
    if (buf == NULL) {
  Branch (3812:9): [True: 0, False: 6.79k]
3813
0
        return PyErr_NoMemory();
3814
0
    }
3815
6.79k
    if (cwd == NULL) {
  Branch (3815:9): [True: 4, False: 6.78k]
3816
4
        PyMem_RawFree(buf);
3817
4
        return posix_error();
3818
4
    }
3819
3820
6.78k
    PyObject *obj;
3821
6.78k
    if (use_bytes) {
  Branch (3821:9): [True: 67, False: 6.72k]
3822
67
        obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3823
67
    }
3824
6.72k
    else {
3825
6.72k
        obj = PyUnicode_DecodeFSDefault(buf);
3826
6.72k
    }
3827
6.78k
    PyMem_RawFree(buf);
3828
3829
6.78k
    return obj;
3830
6.79k
#endif   /* !MS_WINDOWS */
3831
6.79k
}
3832
3833
3834
/*[clinic input]
3835
os.getcwd
3836
3837
Return a unicode string representing the current working directory.
3838
[clinic start generated code]*/
3839
3840
static PyObject *
3841
os_getcwd_impl(PyObject *module)
3842
/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
3843
6.72k
{
3844
6.72k
    return posix_getcwd(0);
3845
6.72k
}
3846
3847
3848
/*[clinic input]
3849
os.getcwdb
3850
3851
Return a bytes string representing the current working directory.
3852
[clinic start generated code]*/
3853
3854
static PyObject *
3855
os_getcwdb_impl(PyObject *module)
3856
/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
3857
67
{
3858
67
    return posix_getcwd(1);
3859
67
}
3860
3861
3862
#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3863
#define HAVE_LINK 1
3864
#endif
3865
3866
#ifdef HAVE_LINK
3867
/*[clinic input]
3868
3869
os.link
3870
3871
    src : path_t
3872
    dst : path_t
3873
    *
3874
    src_dir_fd : dir_fd = None
3875
    dst_dir_fd : dir_fd = None
3876
    follow_symlinks: bool = True
3877
3878
Create a hard link to a file.
3879
3880
If either src_dir_fd or dst_dir_fd is not None, it should be a file
3881
  descriptor open to a directory, and the respective path string (src or dst)
3882
  should be relative; the path will then be relative to that directory.
3883
If follow_symlinks is False, and the last element of src is a symbolic
3884
  link, link will create a link to the symbolic link itself instead of the
3885
  file the link points to.
3886
src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3887
  platform.  If they are unavailable, using them will raise a
3888
  NotImplementedError.
3889
[clinic start generated code]*/
3890
3891
static PyObject *
3892
os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
3893
             int dst_dir_fd, int follow_symlinks)
3894
/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
3895
312
{
3896
#ifdef MS_WINDOWS
3897
    BOOL result = FALSE;
3898
#else
3899
312
    int result;
3900
312
#endif
3901
312
#if defined(HAVE_LINKAT)
3902
312
    int linkat_unavailable = 0;
3903
312
#endif
3904
3905
#ifndef HAVE_LINKAT
3906
    if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3907
        argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3908
        return NULL;
3909
    }
3910
#endif
3911
3912
312
#ifndef MS_WINDOWS
3913
312
    if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
  Branch (3913:10): [True: 312, False: 0]
  Branch (3913:25): [True: 0, False: 312]
  Branch (3913:40): [True: 0, False: 312]
  Branch (3913:53): [True: 0, False: 0]
3914
0
        PyErr_SetString(PyExc_NotImplementedError,
3915
0
                        "link: src and dst must be the same type");
3916
0
        return NULL;
3917
0
    }
3918
312
#endif
3919
3920
312
    if (PySys_Audit("os.link", "OOii", src->object, dst->object,
  Branch (3920:9): [True: 0, False: 312]
3921
312
                    src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
Line
Count
Source
904
312
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3921:21): [True: 311, False: 1]
3922
312
                    dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
Line
Count
Source
904
312
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3922:21): [True: 311, False: 1]
3923
0
        return NULL;
3924
0
    }
3925
3926
#ifdef MS_WINDOWS
3927
    Py_BEGIN_ALLOW_THREADS
3928
    result = CreateHardLinkW(dst->wide, src->wide, NULL);
3929
    Py_END_ALLOW_THREADS
3930
3931
    if (!result)
3932
        return path_error2(src, dst);
3933
#else
3934
312
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
312
#define Py_BEGIN_ALLOW_THREADS { \
143
312
                        PyThreadState *_save; \
144
312
                        _save = PyEval_SaveThread();
3935
312
#ifdef HAVE_LINKAT
3936
312
    if ((src_dir_fd != DEFAULT_DIR_FD) ||
Line
Count
Source
904
312
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3936:9): [True: 1, False: 311]
3937
312
        (dst_dir_fd != DEFAULT_DIR_FD) ||
Line
Count
Source
904
311
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3937:9): [True: 0, False: 311]
3938
312
        (!follow_symlinks)) {
  Branch (3938:9): [True: 0, False: 311]
3939
3940
1
        if (HAVE_LINKAT_RUNTIME) {
Line
Count
Source
167
1
#  define HAVE_LINKAT_RUNTIME 1
  Branch (167:31): [Folded - Ignored]
3941
3942
1
            result = linkat(src_dir_fd, src->narrow,
3943
1
                dst_dir_fd, dst->narrow,
3944
1
                follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
  Branch (3944:17): [True: 1, False: 0]
3945
3946
1
        }
3947
#ifdef __APPLE__
3948
        else {
3949
            if (src_dir_fd == DEFAULT_DIR_FD && dst_dir_fd == DEFAULT_DIR_FD) {
3950
                /* See issue 41355: This matches the behaviour of !HAVE_LINKAT */
3951
                result = link(src->narrow, dst->narrow);
3952
            } else {
3953
                linkat_unavailable = 1;
3954
            }
3955
        }
3956
#endif
3957
1
    }
3958
311
    else
3959
311
#endif /* HAVE_LINKAT */
3960
311
        result = link(src->narrow, dst->narrow);
3961
312
    Py_END_ALLOW_THREADS
Line
Count
Source
147
312
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
312
                 }
3962
3963
312
#ifdef HAVE_LINKAT
3964
312
    if (linkat_unavailable) {
  Branch (3964:9): [True: 0, False: 312]
3965
        /* Either or both dir_fd arguments were specified */
3966
0
        if (src_dir_fd  != DEFAULT_DIR_FD) {
Line
Count
Source
904
0
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (3966:13): [True: 0, False: 0]
3967
0
            argument_unavailable_error("link", "src_dir_fd");
3968
0
        } else {
3969
0
            argument_unavailable_error("link", "dst_dir_fd");
3970
0
        }
3971
0
        return NULL;
3972
0
    }
3973
312
#endif
3974
3975
312
    if (result)
  Branch (3975:9): [True: 6, False: 306]
3976
6
        return path_error2(src, dst);
3977
306
#endif /* MS_WINDOWS */
3978
3979
312
    Py_RETURN_NONE;
Line
Count
Source
661
306
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
306
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
306
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
306
#  define _Py_CAST(type, expr) ((type)(expr))
3980
312
}
3981
#endif
3982
3983
3984
#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3985
static PyObject *
3986
_listdir_windows_no_opendir(path_t *path, PyObject *list)
3987
{
3988
    PyObject *v;
3989
    HANDLE hFindFile = INVALID_HANDLE_VALUE;
3990
    BOOL result;
3991
    wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
3992
    /* only claim to have space for MAX_PATH */
3993
    Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
3994
    wchar_t *wnamebuf = NULL;
3995
3996
    WIN32_FIND_DATAW wFileData;
3997
    const wchar_t *po_wchars;
3998
3999
    if (!path->wide) { /* Default arg: "." */
4000
        po_wchars = L".";
4001
        len = 1;
4002
    } else {
4003
        po_wchars = path->wide;
4004
        len = wcslen(path->wide);
4005
    }
4006
    /* The +5 is so we can append "\\*.*\0" */
4007
    wnamebuf = PyMem_New(wchar_t, len + 5);
4008
    if (!wnamebuf) {
4009
        PyErr_NoMemory();
4010
        goto exit;
4011
    }
4012
    wcscpy(wnamebuf, po_wchars);
4013
    if (len > 0) {
4014
        wchar_t wch = wnamebuf[len-1];
4015
        if (wch != SEP && wch != ALTSEP && wch != L':')
4016
            wnamebuf[len++] = SEP;
4017
        wcscpy(wnamebuf + len, L"*.*");
4018
    }
4019
    if ((list = PyList_New(0)) == NULL) {
4020
        goto exit;
4021
    }
4022
    Py_BEGIN_ALLOW_THREADS
4023
    hFindFile = FindFirstFileW(wnamebuf, &wFileData);
4024
    Py_END_ALLOW_THREADS
4025
    if (hFindFile == INVALID_HANDLE_VALUE) {
4026
        int error = GetLastError();
4027
        if (error == ERROR_FILE_NOT_FOUND)
4028
            goto exit;
4029
        Py_DECREF(list);
4030
        list = path_error(path);
4031
        goto exit;
4032
    }
4033
    do {
4034
        /* Skip over . and .. */
4035
        if (wcscmp(wFileData.cFileName, L".") != 0 &&
4036
            wcscmp(wFileData.cFileName, L"..") != 0) {
4037
            v = PyUnicode_FromWideChar(wFileData.cFileName,
4038
                                       wcslen(wFileData.cFileName));
4039
            if (path->narrow && v) {
4040
                Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
4041
            }
4042
            if (v == NULL) {
4043
                Py_DECREF(list);
4044
                list = NULL;
4045
                break;
4046
            }
4047
            if (PyList_Append(list, v) != 0) {
4048
                Py_DECREF(v);
4049
                Py_DECREF(list);
4050
                list = NULL;
4051
                break;
4052
            }
4053
            Py_DECREF(v);
4054
        }
4055
        Py_BEGIN_ALLOW_THREADS
4056
        result = FindNextFileW(hFindFile, &wFileData);
4057
        Py_END_ALLOW_THREADS
4058
        /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4059
           it got to the end of the directory. */
4060
        if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
4061
            Py_DECREF(list);
4062
            list = path_error(path);
4063
            goto exit;
4064
        }
4065
    } while (result == TRUE);
4066
4067
exit:
4068
    if (hFindFile != INVALID_HANDLE_VALUE) {
4069
        if (FindClose(hFindFile) == FALSE) {
4070
            if (list != NULL) {
4071
                Py_DECREF(list);
4072
                list = path_error(path);
4073
            }
4074
        }
4075
    }
4076
    PyMem_Free(wnamebuf);
4077
4078
    return list;
4079
}  /* end of _listdir_windows_no_opendir */
4080
4081
#else  /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
4082
4083
static PyObject *
4084
_posix_listdir(path_t *path, PyObject *list)
4085
7.17k
{
4086
7.17k
    PyObject *v;
4087
7.17k
    DIR *dirp = NULL;
4088
7.17k
    struct dirent *ep;
4089
7.17k
    int return_str; /* if false, return bytes */
4090
7.17k
#ifdef HAVE_FDOPENDIR
4091
7.17k
    int fd = -1;
4092
7.17k
#endif
4093
4094
7.17k
    errno = 0;
4095
7.17k
#ifdef HAVE_FDOPENDIR
4096
7.17k
    if (path->fd != -1) {
  Branch (4096:9): [True: 55, False: 7.11k]
4097
55
      if (HAVE_FDOPENDIR_RUNTIME) {
Line
Count
Source
168
55
#  define HAVE_FDOPENDIR_RUNTIME 1
  Branch (168:34): [Folded - Ignored]
4098
        /* closedir() closes the FD, so we duplicate it */
4099
55
        fd = _Py_dup(path->fd);
4100
55
        if (fd == -1)
  Branch (4100:13): [True: 0, False: 55]
4101
0
            return NULL;
4102
4103
55
        return_str = 1;
4104
4105
55
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
55
#define Py_BEGIN_ALLOW_THREADS { \
143
55
                        PyThreadState *_save; \
144
55
                        _save = PyEval_SaveThread();
4106
55
        dirp = fdopendir(fd);
4107
55
        Py_END_ALLOW_THREADS
Line
Count
Source
147
55
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
55
                 }
4108
55
      } else {
4109
0
        PyErr_SetString(PyExc_TypeError,
4110
0
            "listdir: path should be string, bytes, os.PathLike or None, not int");
4111
0
        return NULL;
4112
0
      }
4113
55
    }
4114
7.11k
    else
4115
7.11k
#endif
4116
7.11k
    {
4117
7.11k
        const char *name;
4118
7.11k
        if (path->narrow) {
  Branch (4118:13): [True: 5.40k, False: 1.70k]
4119
5.40k
            name = path->narrow;
4120
            /* only return bytes if they specified a bytes-like object */
4121
5.40k
            return_str = !PyObject_CheckBuffer(path->object);
4122
5.40k
        }
4123
1.70k
        else {
4124
1.70k
            name = ".";
4125
1.70k
            return_str = 1;
4126
1.70k
        }
4127
4128
7.11k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
7.11k
#define Py_BEGIN_ALLOW_THREADS { \
143
7.11k
                        PyThreadState *_save; \
144
7.11k
                        _save = PyEval_SaveThread();
4129
7.11k
        dirp = opendir(name);
4130
7.11k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
7.11k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
7.11k
                 }
4131
7.11k
    }
4132
4133
7.17k
    if (dirp == NULL) {
  Branch (4133:9): [True: 509, False: 6.66k]
4134
509
        list = path_error(path);
4135
509
#ifdef HAVE_FDOPENDIR
4136
509
        if (fd != -1) {
  Branch (4136:13): [True: 0, False: 509]
4137
0
            Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
0
#define Py_BEGIN_ALLOW_THREADS { \
143
0
                        PyThreadState *_save; \
144
0
                        _save = PyEval_SaveThread();
4138
0
            close(fd);
4139
0
            Py_END_ALLOW_THREADS
Line
Count
Source
147
0
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
0
                 }
4140
0
        }
4141
509
#endif
4142
509
        goto exit;
4143
509
    }
4144
6.66k
    if ((list = PyList_New(0)) == NULL) {
  Branch (4144:9): [True: 0, False: 6.66k]
4145
0
        goto exit;
4146
0
    }
4147
280k
    for (;;) {
4148
280k
        errno = 0;
4149
280k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
280k
#define Py_BEGIN_ALLOW_THREADS { \
143
280k
                        PyThreadState *_save; \
144
280k
                        _save = PyEval_SaveThread();
4150
280k
        ep = readdir(dirp);
4151
280k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
280k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
280k
                 }
4152
280k
        if (ep == NULL) {
  Branch (4152:13): [True: 6.66k, False: 274k]
4153
6.66k
            if (errno == 0) {
  Branch (4153:17): [True: 6.66k, False: 0]
4154
6.66k
                break;
4155
6.66k
            } else {
4156
0
                Py_DECREF(list);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
4157
0
                list = path_error(path);
4158
0
                goto exit;
4159
0
            }
4160
6.66k
        }
4161
274k
        if (ep->d_name[0] == '.' &&
  Branch (4161:13): [True: 14.3k, False: 259k]
4162
274k
            (NAMLEN(ep) == 1 ||
Line
Count
Source
383
14.3k
#  define NAMLEN(dirent) strlen((dirent)->d_name)
  Branch (4162:14): [True: 6.66k, False: 7.72k]
4163
14.3k
             (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Line
Count
Source
383
6.66k
#  define NAMLEN(dirent) strlen((dirent)->d_name)
  Branch (4163:15): [True: 6.66k, False: 1.06k]
  Branch (4163:39): [True: 6.66k, False: 0]
4164
13.3k
            continue;
4165
260k
        if (return_str)
  Branch (4165:13): [True: 260k, False: 224]
4166
260k
            v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
Line
Count
Source
383
260k
#  define NAMLEN(dirent) strlen((dirent)->d_name)
4167
224
        else
4168
224
            v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Line
Count
Source
383
224
#  define NAMLEN(dirent) strlen((dirent)->d_name)
4169
260k
        if (v == NULL) {
  Branch (4169:13): [True: 0, False: 260k]
4170
0
            Py_CLEAR(list);
Line
Count
Source
587
0
    do {                                        \
588
0
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
589
0
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 0, False: 0]
590
0
            (op) = NULL;                        \
591
0
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
592
0
        }                                       \
593
0
    } while (0)
  Branch (593:14): [Folded - Ignored]
4171
0
            break;
4172
0
        }
4173
260k
        if (PyList_Append(list, v) != 0) {
  Branch (4173:13): [True: 0, False: 260k]
4174
0
            Py_DECREF(v);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
4175
0
            Py_CLEAR(list);
Line
Count
Source
587
0
    do {                                        \
588
0
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
589
0
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 0, False: 0]
590
0
            (op) = NULL;                        \
591
0
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
592
0
        }                                       \
593
0
    } while (0)
  Branch (593:14): [Folded - Ignored]
4176
0
            break;
4177
0
        }
4178
260k
        Py_DECREF(v);
Line
Count
Source
548
260k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
260k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
260k
#  define _Py_CAST(type, expr) ((type)(expr))
4179
260k
    }
4180
4181
7.17k
exit:
4182
7.17k
    if (dirp != NULL) {
  Branch (4182:9): [True: 6.66k, False: 509]
4183
6.66k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
6.66k
#define Py_BEGIN_ALLOW_THREADS { \
143
6.66k
                        PyThreadState *_save; \
144
6.66k
                        _save = PyEval_SaveThread();
4184
6.66k
#ifdef HAVE_FDOPENDIR
4185
6.66k
        if (fd > -1)
  Branch (4185:13): [True: 55, False: 6.60k]
4186
55
            rewinddir(dirp);
4187
6.66k
#endif
4188
6.66k
        closedir(dirp);
4189
6.66k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
6.66k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
6.66k
                 }
4190
6.66k
    }
4191
4192
7.17k
    return list;
4193
6.66k
}  /* end of _posix_listdir */
4194
#endif  /* which OS */
4195
4196
4197
/*[clinic input]
4198
os.listdir
4199
4200
    path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
4201
4202
Return a list containing the names of the files in the directory.
4203
4204
path can be specified as either str, bytes, or a path-like object.  If path is bytes,
4205
  the filenames returned will also be bytes; in all other circumstances
4206
  the filenames returned will be str.
4207
If path is None, uses the path='.'.
4208
On some platforms, path may also be specified as an open file descriptor;\
4209
  the file descriptor must refer to a directory.
4210
  If this functionality is unavailable, using it raises NotImplementedError.
4211
4212
The list is in arbitrary order.  It does not include the special
4213
entries '.' and '..' even if they are present in the directory.
4214
4215
4216
[clinic start generated code]*/
4217
4218
static PyObject *
4219
os_listdir_impl(PyObject *module, path_t *path)
4220
/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
4221
7.17k
{
4222
7.17k
    if (PySys_Audit("os.listdir", "O",
  Branch (4222:9): [True: 0, False: 7.17k]
4223
7.17k
                    path->object ? path->object : Py_None) < 0) {
Line
Count
Source
654
1.70k
#define Py_None (&_Py_NoneStruct)
  Branch (4223:21): [True: 5.46k, False: 1.70k]
4224
0
        return NULL;
4225
0
    }
4226
#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4227
    return _listdir_windows_no_opendir(path, NULL);
4228
#else
4229
7.17k
    return _posix_listdir(path, NULL);
4230
7.17k
#endif
4231
7.17k
}
4232
4233
#ifdef MS_WINDOWS
4234
int
4235
_PyOS_getfullpathname(const wchar_t *path, wchar_t **abspath_p)
4236
{
4237
    wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
4238
    DWORD result;
4239
4240
    result = GetFullPathNameW(path,
4241
                              Py_ARRAY_LENGTH(woutbuf), woutbuf,
4242
                              NULL);
4243
    if (!result) {
4244
        return -1;
4245
    }
4246
4247
    if (result >= Py_ARRAY_LENGTH(woutbuf)) {
4248
        if ((size_t)result <= (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) {
4249
            woutbufp = PyMem_RawMalloc((size_t)result * sizeof(wchar_t));
4250
        }
4251
        else {
4252
            woutbufp = NULL;
4253
        }
4254
        if (!woutbufp) {
4255
            *abspath_p = NULL;
4256
            return 0;
4257
        }
4258
4259
        result = GetFullPathNameW(path, result, woutbufp, NULL);
4260
        if (!result) {
4261
            PyMem_RawFree(woutbufp);
4262
            return -1;
4263
        }
4264
    }
4265
4266
    if (woutbufp != woutbuf) {
4267
        *abspath_p = woutbufp;
4268
        return 0;
4269
    }
4270
4271
    *abspath_p = _PyMem_RawWcsdup(woutbufp);
4272
    return 0;
4273
}
4274
4275
4276
/* A helper function for abspath on win32 */
4277
/*[clinic input]
4278
os._getfullpathname
4279
4280
    path: path_t
4281
    /
4282
4283
[clinic start generated code]*/
4284
4285
static PyObject *
4286
os__getfullpathname_impl(PyObject *module, path_t *path)
4287
/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
4288
{
4289
    wchar_t *abspath;
4290
4291
    if (_PyOS_getfullpathname(path->wide, &abspath) < 0) {
4292
        return win32_error_object("GetFullPathNameW", path->object);
4293
    }
4294
    if (abspath == NULL) {
4295
        return PyErr_NoMemory();
4296
    }
4297
4298
    PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
4299
    PyMem_RawFree(abspath);
4300
    if (str == NULL) {
4301
        return NULL;
4302
    }
4303
    if (path->narrow) {
4304
        Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
4305
    }
4306
    return str;
4307
}
4308
4309
4310
/*[clinic input]
4311
os._getfinalpathname
4312
4313
    path: path_t
4314
    /
4315
4316
A helper function for samepath on windows.
4317
[clinic start generated code]*/
4318
4319
static PyObject *
4320
os__getfinalpathname_impl(PyObject *module, path_t *path)
4321
/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
4322
{
4323
    HANDLE hFile;
4324
    wchar_t buf[MAXPATHLEN], *target_path = buf;
4325
    int buf_size = Py_ARRAY_LENGTH(buf);
4326
    int result_length;
4327
    PyObject *result;
4328
4329
    Py_BEGIN_ALLOW_THREADS
4330
    hFile = CreateFileW(
4331
        path->wide,
4332
        0, /* desired access */
4333
        0, /* share mode */
4334
        NULL, /* security attributes */
4335
        OPEN_EXISTING,
4336
        /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4337
        FILE_FLAG_BACKUP_SEMANTICS,
4338
        NULL);
4339
    Py_END_ALLOW_THREADS
4340
4341
    if (hFile == INVALID_HANDLE_VALUE) {
4342
        return win32_error_object("CreateFileW", path->object);
4343
    }
4344
4345
    /* We have a good handle to the target, use it to determine the
4346
       target path name. */
4347
    while (1) {
4348
        Py_BEGIN_ALLOW_THREADS
4349
        result_length = GetFinalPathNameByHandleW(hFile, target_path,
4350
                                                  buf_size, VOLUME_NAME_DOS);
4351
        Py_END_ALLOW_THREADS
4352
4353
        if (!result_length) {
4354
            result = win32_error_object("GetFinalPathNameByHandleW",
4355
                                         path->object);
4356
            goto cleanup;
4357
        }
4358
4359
        if (result_length < buf_size) {
4360
            break;
4361
        }
4362
4363
        wchar_t *tmp;
4364
        tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4365
                            result_length * sizeof(*tmp));
4366
        if (!tmp) {
4367
            result = PyErr_NoMemory();
4368
            goto cleanup;
4369
        }
4370
4371
        buf_size = result_length;
4372
        target_path = tmp;
4373
    }
4374
4375
    result = PyUnicode_FromWideChar(target_path, result_length);
4376
    if (result && path->narrow) {
4377
        Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
4378
    }
4379
4380
cleanup:
4381
    if (target_path != buf) {
4382
        PyMem_Free(target_path);
4383
    }
4384
    CloseHandle(hFile);
4385
    return result;
4386
}
4387
4388
4389
/*[clinic input]
4390
os._getvolumepathname
4391
4392
    path: path_t
4393
4394
A helper function for ismount on Win32.
4395
[clinic start generated code]*/
4396
4397
static PyObject *
4398
os__getvolumepathname_impl(PyObject *module, path_t *path)
4399
/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
4400
{
4401
    PyObject *result;
4402
    wchar_t *mountpath=NULL;
4403
    size_t buflen;
4404
    BOOL ret;
4405
4406
    /* Volume path should be shorter than entire path */
4407
    buflen = Py_MAX(path->length, MAX_PATH);
4408
4409
    if (buflen > PY_DWORD_MAX) {
4410
        PyErr_SetString(PyExc_OverflowError, "path too long");
4411
        return NULL;
4412
    }
4413
4414
    mountpath = PyMem_New(wchar_t, buflen);
4415
    if (mountpath == NULL)
4416
        return PyErr_NoMemory();
4417
4418
    Py_BEGIN_ALLOW_THREADS
4419
    ret = GetVolumePathNameW(path->wide, mountpath,
4420
                             Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
4421
    Py_END_ALLOW_THREADS
4422
4423
    if (!ret) {
4424
        result = win32_error_object("_getvolumepathname", path->object);
4425
        goto exit;
4426
    }
4427
    result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4428
    if (path->narrow)
4429
        Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
4430
4431
exit:
4432
    PyMem_Free(mountpath);
4433
    return result;
4434
}
4435
4436
4437
/*[clinic input]
4438
os._path_splitroot
4439
4440
    path: path_t
4441
4442
Removes everything after the root on Win32.
4443
[clinic start generated code]*/
4444
4445
static PyObject *
4446
os__path_splitroot_impl(PyObject *module, path_t *path)
4447
/*[clinic end generated code: output=ab7f1a88b654581c input=dc93b1d3984cffb6]*/
4448
{
4449
    wchar_t *buffer;
4450
    wchar_t *end;
4451
    PyObject *result = NULL;
4452
    HRESULT ret;
4453
4454
    buffer = (wchar_t*)PyMem_Malloc(sizeof(wchar_t) * (wcslen(path->wide) + 1));
4455
    if (!buffer) {
4456
        return NULL;
4457
    }
4458
    wcscpy(buffer, path->wide);
4459
    for (wchar_t *p = wcschr(buffer, L'/'); p; p = wcschr(p, L'/')) {
4460
        *p = L'\\';
4461
    }
4462
4463
    Py_BEGIN_ALLOW_THREADS
4464
    ret = PathCchSkipRoot(buffer, &end);
4465
    Py_END_ALLOW_THREADS
4466
    if (FAILED(ret)) {
4467
        result = Py_BuildValue("sO", "", path->object);
4468
    } else if (end != buffer) {
4469
        size_t rootLen = (size_t)(end - buffer);
4470
        result = Py_BuildValue("NN",
4471
            PyUnicode_FromWideChar(path->wide, rootLen),
4472
            PyUnicode_FromWideChar(path->wide + rootLen, -1)
4473
        );
4474
    } else {
4475
        result = Py_BuildValue("Os", path->object, "");
4476
    }
4477
    PyMem_Free(buffer);
4478
4479
    return result;
4480
}
4481
4482
4483
#endif /* MS_WINDOWS */
4484
4485
4486
/*[clinic input]
4487
os._path_normpath
4488
4489
    path: object
4490
4491
Basic path normalization.
4492
[clinic start generated code]*/
4493
4494
static PyObject *
4495
os__path_normpath_impl(PyObject *module, PyObject *path)
4496
/*[clinic end generated code: output=b94d696d828019da input=5e90c39e12549dc0]*/
4497
25.3k
{
4498
25.3k
    if (!PyUnicode_Check(path)) {
Line
Count
Source
115
25.3k
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
Line
Count
Source
782
25.3k
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (4498:9): [True: 0, False: 25.3k]
4499
0
        PyErr_Format(PyExc_TypeError, "expected 'str', not '%.200s'",
4500
0
            Py_TYPE(path)->tp_name);
Line
Count
Source
138
0
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
4501
0
        return NULL;
4502
0
    }
4503
25.3k
    Py_ssize_t len;
4504
25.3k
    wchar_t *buffer = PyUnicode_AsWideCharString(path, &len);
4505
25.3k
    if (!buffer) {
  Branch (4505:9): [True: 0, False: 25.3k]
4506
0
        return NULL;
4507
0
    }
4508
25.3k
    PyObject *result = PyUnicode_FromWideChar(_Py_normpath(buffer, len), -1);
4509
25.3k
    PyMem_Free(buffer);
4510
25.3k
    return result;
4511
25.3k
}
4512
4513
/*[clinic input]
4514
os.mkdir
4515
4516
    path : path_t
4517
4518
    mode: int = 0o777
4519
4520
    *
4521
4522
    dir_fd : dir_fd(requires='mkdirat') = None
4523
4524
# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4525
4526
Create a directory.
4527
4528
If dir_fd is not None, it should be a file descriptor open to a directory,
4529
  and path should be relative; path will then be relative to that directory.
4530
dir_fd may not be implemented on your platform.
4531
  If it is unavailable, using it will raise a NotImplementedError.
4532
4533
The mode argument is ignored on Windows.
4534
[clinic start generated code]*/
4535
4536
static PyObject *
4537
os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4538
/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
4539
8.20k
{
4540
8.20k
    int result;
4541
8.20k
#ifdef HAVE_MKDIRAT
4542
8.20k
    int mkdirat_unavailable = 0;
4543
8.20k
#endif
4544
4545
8.20k
    if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
  Branch (4545:9): [True: 0, False: 8.20k]
4546
8.20k
                    dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
Line
Count
Source
904
8.20k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (4546:21): [True: 8.20k, False: 1]
4547
0
        return NULL;
4548
0
    }
4549
4550
#ifdef MS_WINDOWS
4551
    Py_BEGIN_ALLOW_THREADS
4552
    result = CreateDirectoryW(path->wide, NULL);
4553
    Py_END_ALLOW_THREADS
4554
4555
    if (!result)
4556
        return path_error(path);
4557
#else
4558
8.20k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
8.20k
#define Py_BEGIN_ALLOW_THREADS { \
143
8.20k
                        PyThreadState *_save; \
144
8.20k
                        _save = PyEval_SaveThread();
4559
8.20k
#if HAVE_MKDIRAT
4560
8.20k
    if (dir_fd != DEFAULT_DIR_FD) {
Line
Count
Source
904
8.20k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (4560:9): [True: 1, False: 8.20k]
4561
1
      if (HAVE_MKDIRAT_RUNTIME) {
Line
Count
Source
169
1
#  define HAVE_MKDIRAT_RUNTIME 1
  Branch (169:32): [Folded - Ignored]
4562
1
        result = mkdirat(dir_fd, path->narrow, mode);
4563
4564
1
      } else {
4565
0
        mkdirat_unavailable = 1;
4566
0
      }
4567
1
    } else
4568
8.20k
#endif
4569
#if defined(__WATCOMC__) && !defined(__QNX__)
4570
        result = mkdir(path->narrow);
4571
#else
4572
8.20k
        result = mkdir(path->narrow, mode);
4573
8.20k
#endif
4574
8.20k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
8.20k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
8.20k
                 }
4575
4576
8.20k
#if HAVE_MKDIRAT
4577
8.20k
    if (mkdirat_unavailable) {
  Branch (4577:9): [True: 0, False: 8.20k]
4578
0
        argument_unavailable_error(NULL, "dir_fd");
4579
0
        return NULL;
4580
0
    }
4581
8.20k
#endif
4582
4583
8.20k
    if (result < 0)
  Branch (4583:9): [True: 590, False: 7.61k]
4584
590
        return path_error(path);
4585
7.61k
#endif /* MS_WINDOWS */
4586
8.20k
    Py_RETURN_NONE;
Line
Count
Source
661
7.61k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
7.61k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
7.61k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7.61k
#  define _Py_CAST(type, expr) ((type)(expr))
4587
8.20k
}
4588
4589
4590
/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4591
#if defined(HAVE_SYS_RESOURCE_H)
4592
#include <sys/resource.h>
4593
#endif
4594
4595
4596
#ifdef HAVE_NICE
4597
/*[clinic input]
4598
os.nice
4599
4600
    increment: int
4601
    /
4602
4603
Add increment to the priority of process and return the new priority.
4604
[clinic start generated code]*/
4605
4606
static PyObject *
4607
os_nice_impl(PyObject *module, int increment)
4608
/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
4609
0
{
4610
0
    int value;
4611
4612
    /* There are two flavours of 'nice': one that returns the new
4613
       priority (as required by almost all standards out there) and the
4614
       Linux/FreeBSD one, which returns '0' on success and advices
4615
       the use of getpriority() to get the new priority.
4616
4617
       If we are of the nice family that returns the new priority, we
4618
       need to clear errno before the call, and check if errno is filled
4619
       before calling posix_error() on a returnvalue of -1, because the
4620
       -1 may be the actual new priority! */
4621
4622
0
    errno = 0;
4623
0
    value = nice(increment);
4624
#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
4625
    if (value == 0)
4626
        value = getpriority(PRIO_PROCESS, 0);
4627
#endif
4628
0
    if (value == -1 && errno != 0)
  Branch (4628:9): [True: 0, False: 0]
  Branch (4628:24): [True: 0, False: 0]
4629
        /* either nice() or getpriority() returned an error */
4630
0
        return posix_error();
4631
0
    return PyLong_FromLong((long) value);
4632
0
}
4633
#endif /* HAVE_NICE */
4634
4635
4636
#ifdef HAVE_GETPRIORITY
4637
/*[clinic input]
4638
os.getpriority
4639
4640
    which: int
4641
    who: int
4642
4643
Return program scheduling priority.
4644
[clinic start generated code]*/
4645
4646
static PyObject *
4647
os_getpriority_impl(PyObject *module, int which, int who)
4648
/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
4649
2
{
4650
2
    int retval;
4651
4652
2
    errno = 0;
4653
2
    retval = getpriority(which, who);
4654
2
    if (errno != 0)
  Branch (4654:9): [True: 0, False: 2]
4655
0
        return posix_error();
4656
2
    return PyLong_FromLong((long)retval);
4657
2
}
4658
#endif /* HAVE_GETPRIORITY */
4659
4660
4661
#ifdef HAVE_SETPRIORITY
4662
/*[clinic input]
4663
os.setpriority
4664
4665
    which: int
4666
    who: int
4667
    priority: int
4668
4669
Set program scheduling priority.
4670
[clinic start generated code]*/
4671
4672
static PyObject *
4673
os_setpriority_impl(PyObject *module, int which, int who, int priority)
4674
/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
4675
2
{
4676
2
    int retval;
4677
4678
2
    retval = setpriority(which, who, priority);
4679
2
    if (retval == -1)
  Branch (4679:9): [True: 1, False: 1]
4680
1
        return posix_error();
4681
2
    Py_RETURN_NONE;
Line
Count
Source
661
1
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
4682
2
}
4683
#endif /* HAVE_SETPRIORITY */
4684
4685
4686
static PyObject *
4687
internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace)
4688
1.69k
{
4689
1.69k
    const char *function_name = is_replace ? "replace" : "rename";
  Branch (4689:33): [True: 795, False: 900]
4690
1.69k
    int dir_fd_specified;
4691
4692
1.69k
#ifdef HAVE_RENAMEAT
4693
1.69k
    int renameat_unavailable = 0;
4694
1.69k
#endif
4695
4696
#ifdef MS_WINDOWS
4697
    BOOL result;
4698
    int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
4699
#else
4700
1.69k
    int result;
4701
1.69k
#endif
4702
4703
1.69k
    dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
Line
Count
Source
904
1.69k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (4703:24): [True: 1, False: 1.69k]
4704
1.69k
                       (dst_dir_fd != DEFAULT_DIR_FD);
Line
Count
Source
904
1.69k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (4704:24): [True: 0, False: 1.69k]
4705
#ifndef HAVE_RENAMEAT
4706
    if (dir_fd_specified) {
4707
        argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4708
        return NULL;
4709
    }
4710
#endif
4711
4712
1.69k
    if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
  Branch (4712:9): [True: 0, False: 1.69k]
4713
1.69k
                    src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
Line
Count
Source
904
1.69k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (4713:21): [True: 1.69k, False: 1]
4714
1.69k
                    dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
Line
Count
Source
904
1.69k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (4714:21): [True: 1.69k, False: 1]
4715
0
        return NULL;
4716
0
    }
4717
4718
#ifdef MS_WINDOWS
4719
    Py_BEGIN_ALLOW_THREADS
4720
    result = MoveFileExW(src->wide, dst->wide, flags);
4721
    Py_END_ALLOW_THREADS
4722
4723
    if (!result)
4724
        return path_error2(src, dst);
4725
4726
#else
4727
1.69k
    if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
  Branch (4727:10): [True: 1.69k, False: 0]
  Branch (4727:25): [True: 0, False: 1.69k]
  Branch (4727:40): [True: 0, False: 1.69k]
  Branch (4727:53): [True: 0, False: 0]
4728
0
        PyErr_Format(PyExc_ValueError,
4729
0
                     "%s: src and dst must be the same type", function_name);
4730
0
        return NULL;
4731
0
    }
4732
4733
1.69k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
1.69k
#define Py_BEGIN_ALLOW_THREADS { \
143
1.69k
                        PyThreadState *_save; \
144
1.69k
                        _save = PyEval_SaveThread();
4734
1.69k
#ifdef HAVE_RENAMEAT
4735
1.69k
    if (dir_fd_specified) {
  Branch (4735:9): [True: 1, False: 1.69k]
4736
1
        if (HAVE_RENAMEAT_RUNTIME) {
Line
Count
Source
170
1
#  define HAVE_RENAMEAT_RUNTIME 1
  Branch (170:33): [Folded - Ignored]
4737
1
            result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
4738
1
        } else {
4739
0
            renameat_unavailable = 1;
4740
0
        }
4741
1
    } else
4742
1.69k
#endif
4743
1.69k
    result = rename(src->narrow, dst->narrow);
4744
1.69k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
1.69k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
1.69k
                 }
4745
4746
4747
1.69k
#ifdef HAVE_RENAMEAT
4748
1.69k
    if (renameat_unavailable) {
  Branch (4748:9): [True: 0, False: 1.69k]
4749
0
        argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4750
0
        return NULL;
4751
0
    }
4752
1.69k
#endif
4753
4754
1.69k
    if (result)
  Branch (4754:9): [True: 121, False: 1.57k]
4755
121
        return path_error2(src, dst);
4756
1.57k
#endif
4757
1.69k
    Py_RETURN_NONE;
Line
Count
Source
661
1.57k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1.57k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1.57k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1.57k
#  define _Py_CAST(type, expr) ((type)(expr))
4758
1.69k
}
4759
4760
4761
/*[clinic input]
4762
os.rename
4763
4764
    src : path_t
4765
    dst : path_t
4766
    *
4767
    src_dir_fd : dir_fd = None
4768
    dst_dir_fd : dir_fd = None
4769
4770
Rename a file or directory.
4771
4772
If either src_dir_fd or dst_dir_fd is not None, it should be a file
4773
  descriptor open to a directory, and the respective path string (src or dst)
4774
  should be relative; the path will then be relative to that directory.
4775
src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4776
  If they are unavailable, using them will raise a NotImplementedError.
4777
[clinic start generated code]*/
4778
4779
static PyObject *
4780
os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4781
               int dst_dir_fd)
4782
/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
4783
900
{
4784
900
    return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
4785
900
}
4786
4787
4788
/*[clinic input]
4789
os.replace = os.rename
4790
4791
Rename a file or directory, overwriting the destination.
4792
4793
If either src_dir_fd or dst_dir_fd is not None, it should be a file
4794
  descriptor open to a directory, and the respective path string (src or dst)
4795
  should be relative; the path will then be relative to that directory.
4796
src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4797
  If they are unavailable, using them will raise a NotImplementedError.
4798
[clinic start generated code]*/
4799
4800
static PyObject *
4801
os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4802
                int dst_dir_fd)
4803
/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
4804
795
{
4805
795
    return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4806
795
}
4807
4808
4809
/*[clinic input]
4810
os.rmdir
4811
4812
    path: path_t
4813
    *
4814
    dir_fd: dir_fd(requires='unlinkat') = None
4815
4816
Remove a directory.
4817
4818
If dir_fd is not None, it should be a file descriptor open to a directory,
4819
  and path should be relative; path will then be relative to that directory.
4820
dir_fd may not be implemented on your platform.
4821
  If it is unavailable, using it will raise a NotImplementedError.
4822
[clinic start generated code]*/
4823
4824
static PyObject *
4825
os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4826
/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
4827
9.03k
{
4828
9.03k
    int result;
4829
9.03k
#ifdef HAVE_UNLINKAT
4830
9.03k
    int unlinkat_unavailable = 0;
4831
9.03k
#endif
4832
4833
9.03k
    if (PySys_Audit("os.rmdir", "Oi", path->object,
  Branch (4833:9): [True: 0, False: 9.03k]
4834
9.03k
                    dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
Line
Count
Source
904
9.03k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (4834:21): [True: 3.72k, False: 5.30k]
4835
0
        return NULL;
4836
0
    }
4837
4838
9.03k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
9.03k
#define Py_BEGIN_ALLOW_THREADS { \
143
9.03k
                        PyThreadState *_save; \
144
9.03k
                        _save = PyEval_SaveThread();
4839
#ifdef MS_WINDOWS
4840
    /* Windows, success=1, UNIX, success=0 */
4841
    result = !RemoveDirectoryW(path->wide);
4842
#else
4843
9.03k
#ifdef HAVE_UNLINKAT
4844
9.03k
    if (dir_fd != DEFAULT_DIR_FD) {
Line
Count
Source
904
9.03k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (4844:9): [True: 5.30k, False: 3.72k]
4845
5.30k
      if (HAVE_UNLINKAT_RUNTIME) {
Line
Count
Source
171
5.30k
#  define HAVE_UNLINKAT_RUNTIME 1
  Branch (171:33): [Folded - Ignored]
4846
5.30k
        result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
4847
5.30k
      } else {
4848
0
        unlinkat_unavailable = 1;
4849
0
        result = -1;
4850
0
      }
4851
5.30k
    } else
4852
3.72k
#endif
4853
3.72k
        result = rmdir(path->narrow);
4854
9.03k
#endif
4855
9.03k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
9.03k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
9.03k
                 }
4856
4857
9.03k
#ifdef HAVE_UNLINKAT
4858
9.03k
    if (unlinkat_unavailable) {
  Branch (4858:9): [True: 0, False: 9.03k]
4859
0
        argument_unavailable_error("rmdir", "dir_fd");
4860
0
        return NULL;
4861
0
    }
4862
9.03k
#endif
4863
4864
9.03k
    if (result)
  Branch (4864:9): [True: 414, False: 8.61k]
4865
414
        return path_error(path);
4866
4867
9.03k
    Py_RETURN_NONE;
Line
Count
Source
661
8.61k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
8.61k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
8.61k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8.61k
#  define _Py_CAST(type, expr) ((type)(expr))
4868
9.03k
}
4869
4870
4871
#ifdef HAVE_SYSTEM
4872
#ifdef MS_WINDOWS
4873
/*[clinic input]
4874
os.system -> long
4875
4876
    command: Py_UNICODE
4877
4878
Execute the command in a subshell.
4879
[clinic start generated code]*/
4880
4881
static long
4882
os_system_impl(PyObject *module, const Py_UNICODE *command)
4883
/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
4884
{
4885
    long result;
4886
4887
    if (PySys_Audit("os.system", "(u)", command) < 0) {
4888
        return -1;
4889
    }
4890
4891
    Py_BEGIN_ALLOW_THREADS
4892
    _Py_BEGIN_SUPPRESS_IPH
4893
    result = _wsystem(command);
4894
    _Py_END_SUPPRESS_IPH
4895
    Py_END_ALLOW_THREADS
4896
    return result;
4897
}
4898
#else /* MS_WINDOWS */
4899
/*[clinic input]
4900
os.system -> long
4901
4902
    command: FSConverter
4903
4904
Execute the command in a subshell.
4905
[clinic start generated code]*/
4906
4907
static long
4908
os_system_impl(PyObject *module, PyObject *command)
4909
/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
4910
4
{
4911
4
    long result;
4912
4
    const char *bytes = PyBytes_AsString(command);
4913
4914
4
    if (PySys_Audit("os.system", "(O)", command) < 0) {
  Branch (4914:9): [True: 0, False: 4]
4915
0
        return -1;
4916
0
    }
4917
4918
4
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
4
#define Py_BEGIN_ALLOW_THREADS { \
143
4
                        PyThreadState *_save; \
144
4
                        _save = PyEval_SaveThread();
4919
4
    result = system(bytes);
4920
4
    Py_END_ALLOW_THREADS
Line
Count
Source
147
4
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
4
                 }
4921
4
    return result;
4922
4
}
4923
#endif
4924
#endif /* HAVE_SYSTEM */
4925
4926
4927
#ifdef HAVE_UMASK
4928
/*[clinic input]
4929
os.umask
4930
4931
    mask: int
4932
    /
4933
4934
Set the current numeric umask and return the previous umask.
4935
[clinic start generated code]*/
4936
4937
static PyObject *
4938
os_umask_impl(PyObject *module, int mask)
4939
/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
4940
486
{
4941
486
    int i = (int)umask(mask);
4942
486
    if (i < 0)
  Branch (4942:9): [True: 0, False: 486]
4943
0
        return posix_error();
4944
486
    return PyLong_FromLong((long)i);
4945
486
}
4946
#endif
4947
4948
#ifdef MS_WINDOWS
4949
4950
/* override the default DeleteFileW behavior so that directory
4951
symlinks can be removed with this function, the same as with
4952
Unix symlinks */
4953
BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4954
{
4955
    WIN32_FILE_ATTRIBUTE_DATA info;
4956
    WIN32_FIND_DATAW find_data;
4957
    HANDLE find_data_handle;
4958
    int is_directory = 0;
4959
    int is_link = 0;
4960
4961
    if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4962
        is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
4963
4964
        /* Get WIN32_FIND_DATA structure for the path to determine if
4965
           it is a symlink */
4966
        if(is_directory &&
4967
           info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4968
            find_data_handle = FindFirstFileW(lpFileName, &find_data);
4969
4970
            if(find_data_handle != INVALID_HANDLE_VALUE) {
4971
                /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4972
                   IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4973
                is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4974
                          find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
4975
                FindClose(find_data_handle);
4976
            }
4977
        }
4978
    }
4979
4980
    if (is_directory && is_link)
4981
        return RemoveDirectoryW(lpFileName);
4982
4983
    return DeleteFileW(lpFileName);
4984
}
4985
#endif /* MS_WINDOWS */
4986
4987
4988
/*[clinic input]
4989
os.unlink
4990
4991
    path: path_t
4992
    *
4993
    dir_fd: dir_fd(requires='unlinkat')=None
4994
4995
Remove a file (same as remove()).
4996
4997
If dir_fd is not None, it should be a file descriptor open to a directory,
4998
  and path should be relative; path will then be relative to that directory.
4999
dir_fd may not be implemented on your platform.
5000
  If it is unavailable, using it will raise a NotImplementedError.
5001
5002
[clinic start generated code]*/
5003
5004
static PyObject *
5005
os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
5006
/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
5007
45.8k
{
5008
45.8k
    int result;
5009
45.8k
#ifdef HAVE_UNLINKAT
5010
45.8k
    int unlinkat_unavailable = 0;
5011
45.8k
#endif
5012
5013
45.8k
    if (PySys_Audit("os.remove", "Oi", path->object,
  Branch (5013:9): [True: 0, False: 45.8k]
5014
45.8k
                    dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
Line
Count
Source
904
45.8k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (5014:21): [True: 16.8k, False: 29.0k]
5015
0
        return NULL;
5016
0
    }
5017
5018
45.8k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
45.8k
#define Py_BEGIN_ALLOW_THREADS { \
143
45.8k
                        PyThreadState *_save; \
144
45.8k
                        _save = PyEval_SaveThread();
5019
45.8k
    _Py_BEGIN_SUPPRESS_IPH
5020
#ifdef MS_WINDOWS
5021
    /* Windows, success=1, UNIX, success=0 */
5022
    result = !Py_DeleteFileW(path->wide);
5023
#else
5024
45.8k
#ifdef HAVE_UNLINKAT
5025
45.8k
    if (dir_fd != DEFAULT_DIR_FD) {
Line
Count
Source
904
45.8k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (5025:9): [True: 29.0k, False: 16.8k]
5026
29.0k
      if (HAVE_UNLINKAT_RUNTIME) {
Line
Count
Source
171
29.0k
#  define HAVE_UNLINKAT_RUNTIME 1
  Branch (171:33): [Folded - Ignored]
5027
5028
29.0k
        result = unlinkat(dir_fd, path->narrow, 0);
5029
29.0k
      } else {
5030
0
        unlinkat_unavailable = 1;
5031
0
      }
5032
29.0k
    } else
5033
16.8k
#endif /* HAVE_UNLINKAT */
5034
16.8k
        result = unlink(path->narrow);
5035
45.8k
#endif
5036
45.8k
    _Py_END_SUPPRESS_IPH
5037
45.8k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
45.8k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
45.8k
                 }
5038
5039
45.8k
#ifdef HAVE_UNLINKAT
5040
45.8k
    if (unlinkat_unavailable) {
  Branch (5040:9): [True: 0, False: 45.8k]
5041
0
        argument_unavailable_error(NULL, "dir_fd");
5042
0
        return NULL;
5043
0
    }
5044
45.8k
#endif
5045
5046
45.8k
    if (result)
  Branch (5046:9): [True: 7.47k, False: 38.3k]
5047
7.47k
        return path_error(path);
5048
5049
45.8k
    Py_RETURN_NONE;
Line
Count
Source
661
38.3k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
38.3k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
38.3k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
38.3k
#  define _Py_CAST(type, expr) ((type)(expr))
5050
45.8k
}
5051
5052
5053
/*[clinic input]
5054
os.remove = os.unlink
5055
5056
Remove a file (same as unlink()).
5057
5058
If dir_fd is not None, it should be a file descriptor open to a directory,
5059
  and path should be relative; path will then be relative to that directory.
5060
dir_fd may not be implemented on your platform.
5061
  If it is unavailable, using it will raise a NotImplementedError.
5062
[clinic start generated code]*/
5063
5064
static PyObject *
5065
os_remove_impl(PyObject *module, path_t *path, int dir_fd)
5066
/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
5067
1.36k
{
5068
1.36k
    return os_unlink_impl(module, path, dir_fd);
5069
1.36k
}
5070
5071
5072
static PyStructSequence_Field uname_result_fields[] = {
5073
    {"sysname",    "operating system name"},
5074
    {"nodename",   "name of machine on network (implementation-defined)"},
5075
    {"release",    "operating system release"},
5076
    {"version",    "operating system version"},
5077
    {"machine",    "hardware identifier"},
5078
    {NULL}
5079
};
5080
5081
PyDoc_STRVAR(uname_result__doc__,
5082
"uname_result: Result from os.uname().\n\n\
5083
This object may be accessed either as a tuple of\n\
5084
  (sysname, nodename, release, version, machine),\n\
5085
or via the attributes sysname, nodename, release, version, and machine.\n\
5086
\n\
5087
See os.uname for more information.");
5088
5089
static PyStructSequence_Desc uname_result_desc = {
5090
    MODNAME ".uname_result", /* name */
5091
    uname_result__doc__, /* doc */
5092
    uname_result_fields,
5093
    5
5094
};
5095
5096
#ifdef HAVE_UNAME
5097
/*[clinic input]
5098
os.uname
5099
5100
Return an object identifying the current operating system.
5101
5102
The object behaves like a named tuple with the following fields:
5103
  (sysname, nodename, release, version, machine)
5104
5105
[clinic start generated code]*/
5106
5107
static PyObject *
5108
os_uname_impl(PyObject *module)
5109
/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
5110
131
{
5111
131
    struct utsname u;
5112
131
    int res;
5113
131
    PyObject *value;
5114
5115
131
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
131
#define Py_BEGIN_ALLOW_THREADS { \
143
131
                        PyThreadState *_save; \
144
131
                        _save = PyEval_SaveThread();
5116
131
    res = uname(&u);
5117
131
    Py_END_ALLOW_THREADS
Line
Count
Source
147
131
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
131
                 }
5118
131
    if (res < 0)
  Branch (5118:9): [True: 0, False: 131]
5119
0
        return posix_error();
5120
5121
131
    PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
5122
131
    value = PyStructSequence_New((PyTypeObject *)UnameResultType);
5123
131
    if (value == NULL)
  Branch (5123:9): [True: 0, False: 131]
5124
0
        return NULL;
5125
5126
131
#define SET(i, field) \
5127
655
    { \
5128
655
    PyObject *o = PyUnicode_DecodeFSDefault(field); \
5129
655
    if (!o) { \
5130
0
        Py_DECREF(value); \
5131
0
        return NULL; \
5132
0
    } \
5133
655
    PyStructSequence_SET_ITEM(value, i, o); \
5134
655
    } \
5135
131
5136
262
    SET(0, u.sysname);
Line
Count
Source
5127
131
    { \
5128
131
    PyObject *o = PyUnicode_DecodeFSDefault(field); \
5129
131
    if (!o) { \
  Branch (5129:9): [True: 0, False: 131]
5130
0
        Py_DECREF(value); \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
5131
0
        return NULL; \
5132
0
    } \
5133
131
    PyStructSequence_SET_ITEM(value, i, o); \
Line
Count
Source
38
131
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
131
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
131
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
131
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
131
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
131
#  define _Py_CAST(type, expr) ((type)(expr))
5134
131
    } \
5137
262
    SET(1, u.nodename);
Line
Count
Source
5127
131
    { \
5128
131
    PyObject *o = PyUnicode_DecodeFSDefault(field); \
5129
131
    if (!o) { \
  Branch (5129:9): [True: 0, False: 131]
5130
0
        Py_DECREF(value); \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
5131
0
        return NULL; \
5132
0
    } \
5133
131
    PyStructSequence_SET_ITEM(value, i, o); \
Line
Count
Source
38
131
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
131
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
131
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
131
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
131
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
131
#  define _Py_CAST(type, expr) ((type)(expr))
5134
131
    } \
5138
131
    SET(2, u.release);
Line
Count
Source
5127
131
    { \
5128
131
    PyObject *o = PyUnicode_DecodeFSDefault(field); \
5129
131
    if (!o) { \
  Branch (5129:9): [True: 0, False: 131]
5130
0
        Py_DECREF(value); \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
5131
0
        return NULL; \
5132
0
    } \
5133
131
    PyStructSequence_SET_ITEM(value, i, o); \
Line
Count
Source
38
131
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
131
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
131
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
131
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
131
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
131
#  define _Py_CAST(type, expr) ((type)(expr))
5134
131
    } \
5139
131
    SET(3, u.version);
Line
Count
Source
5127
131
    { \
5128
131
    PyObject *o = PyUnicode_DecodeFSDefault(field); \
5129
131
    if (!o) { \
  Branch (5129:9): [True: 0, False: 131]
5130
0
        Py_DECREF(value); \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
5131
0
        return NULL; \
5132
0
    } \
5133
131
    PyStructSequence_SET_ITEM(value, i, o); \
Line
Count
Source
38
131
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
131
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
131
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
131
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
131
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
131
#  define _Py_CAST(type, expr) ((type)(expr))
5134
131
    } \
5140
131
    SET(4, u.machine);
Line
Count
Source
5127
131
    { \
5128
131
    PyObject *o = PyUnicode_DecodeFSDefault(field); \
5129
131
    if (!o) { \
  Branch (5129:9): [True: 0, False: 131]
5130
0
        Py_DECREF(value); \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
5131
0
        return NULL; \
5132
0
    } \
5133
131
    PyStructSequence_SET_ITEM(value, i, o); \
Line
Count
Source
38
131
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
131
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
131
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
131
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
131
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
131
#  define _Py_CAST(type, expr) ((type)(expr))
5134
131
    } \
5141
5142
131
#undef SET
5143
5144
131
    return value;
5145
131
}
5146
#endif /* HAVE_UNAME */
5147
5148
5149
5150
typedef struct {
5151
    int    now;
5152
    time_t atime_s;
5153
    long   atime_ns;
5154
    time_t mtime_s;
5155
    long   mtime_ns;
5156
} utime_t;
5157
5158
/*
5159
 * these macros assume that "ut" is a pointer to a utime_t
5160
 * they also intentionally leak the declaration of a pointer named "time"
5161
 */
5162
#define UTIME_TO_TIMESPEC \
5163
9.01k
    struct timespec ts[2]; \
5164
9.01k
    struct timespec *time; \
5165
9.01k
    if (ut->now) \
5166
9.01k
        time = NULL; \
5167
9.01k
    else { \
5168
8.94k
        ts[0].tv_sec = ut->atime_s; \
5169
8.94k
        ts[0].tv_nsec = ut->atime_ns; \
5170
8.94k
        ts[1].tv_sec = ut->mtime_s; \
5171
8.94k
        ts[1].tv_nsec = ut->mtime_ns; \
5172
8.94k
        time = ts; \
5173
8.94k
    } \
5174
5175
#define UTIME_TO_TIMEVAL \
5176
0
    struct timeval tv[2]; \
5177
0
    struct timeval *time; \
5178
0
    if (ut->now) \
5179
0
        time = NULL; \
5180
0
    else { \
5181
0
        tv[0].tv_sec = ut->atime_s; \
5182
0
        tv[0].tv_usec = ut->atime_ns / 1000; \
5183
0
        tv[1].tv_sec = ut->mtime_s; \
5184
0
        tv[1].tv_usec = ut->mtime_ns / 1000; \
5185
0
        time = tv; \
5186
0
    } \
5187
5188
#define UTIME_TO_UTIMBUF \
5189
    struct utimbuf u; \
5190
    struct utimbuf *time; \
5191
    if (ut->now) \
5192
        time = NULL; \
5193
    else { \
5194
        u.actime = ut->atime_s; \
5195
        u.modtime = ut->mtime_s; \
5196
        time = &u; \
5197
    }
5198
5199
#define UTIME_TO_TIME_T \
5200
    time_t timet[2]; \
5201
    time_t *time; \
5202
    if (ut->now) \
5203
        time = NULL; \
5204
    else { \
5205
        timet[0] = ut->atime_s; \
5206
        timet[1] = ut->mtime_s; \
5207
        time = timet; \
5208
    } \
5209
5210
5211
#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
5212
5213
static int
5214
utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
5215
8
{
5216
#if defined(__APPLE__) &&  defined(HAVE_UTIMENSAT)
5217
    if (HAVE_UTIMENSAT_RUNTIME) {
5218
        int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5219
        UTIME_TO_TIMESPEC;
5220
        return utimensat(dir_fd, path, time, flags);
5221
    }  else {
5222
        errno = ENOSYS;
5223
        return -1;
5224
    }
5225
#elif defined(HAVE_UTIMENSAT)
5226
8
    int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
  Branch (5226:17): [True: 7, False: 1]
5227
8
    UTIME_TO_TIMESPEC;
Line
Count
Source
5163
8
    struct timespec ts[2]; \
5164
8
    struct timespec *time; \
5165
8
    if (ut->now) \
  Branch (5165:9): [True: 3, False: 5]
5166
8
        time = NULL; \
5167
8
    else { \
5168
5
        ts[0].tv_sec = ut->atime_s; \
5169
5
        ts[0].tv_nsec = ut->atime_ns; \
5170
5
        ts[1].tv_sec = ut->mtime_s; \
5171
5
        ts[1].tv_nsec = ut->mtime_ns; \
5172
5
        time = ts; \
5173
5
    } \
5228
8
    return utimensat(dir_fd, path, time, flags);
5229
#elif defined(HAVE_FUTIMESAT)
5230
    UTIME_TO_TIMEVAL;
5231
    /*
5232
     * follow_symlinks will never be false here;
5233
     * we only allow !follow_symlinks and dir_fd together
5234
     * if we have utimensat()
5235
     */
5236
    assert(follow_symlinks);
5237
    return futimesat(dir_fd, path, time);
5238
#endif
5239
8
}
5240
5241
13
    #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
5242
#else
5243
    #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
5244
#endif
5245
5246
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
5247
5248
static int
5249
utime_fd(utime_t *ut, int fd)
5250
7
{
5251
7
#ifdef HAVE_FUTIMENS
5252
5253
7
    if (HAVE_FUTIMENS_RUNTIME) {
Line
Count
Source
175
7
#  define HAVE_FUTIMENS_RUNTIME 1
  Branch (175:33): [Folded - Ignored]
5254
5255
7
    UTIME_TO_TIMESPEC;
Line
Count
Source
5163
7
    struct timespec ts[2]; \
5164
7
    struct timespec *time; \
5165
7
    if (ut->now) \
  Branch (5165:9): [True: 2, False: 5]
5166
7
        time = NULL; \
5167
7
    else { \
5168
5
        ts[0].tv_sec = ut->atime_s; \
5169
5
        ts[0].tv_nsec = ut->atime_ns; \
5170
5
        ts[1].tv_sec = ut->mtime_s; \
5171
5
        ts[1].tv_nsec = ut->mtime_ns; \
5172
5
        time = ts; \
5173
5
    } \
5256
7
    return futimens(fd, time);
5257
5258
7
    } else
5259
#ifndef HAVE_FUTIMES
5260
    {
5261
        /* Not sure if this can happen */
5262
        PyErr_SetString(
5263
            PyExc_RuntimeError,
5264
            "neither futimens nor futimes are supported"
5265
            " on this system");
5266
        return -1;
5267
    }
5268
#endif
5269
5270
0
#endif
5271
0
#ifdef HAVE_FUTIMES
5272
0
    {
5273
0
    UTIME_TO_TIMEVAL;
Line
Count
Source
5176
0
    struct timeval tv[2]; \
5177
0
    struct timeval *time; \
5178
0
    if (ut->now) \
  Branch (5178:9): [True: 0, False: 0]
5179
0
        time = NULL; \
5180
0
    else { \
5181
0
        tv[0].tv_sec = ut->atime_s; \
5182
0
        tv[0].tv_usec = ut->atime_ns / 1000; \
5183
0
        tv[1].tv_sec = ut->mtime_s; \
5184
0
        tv[1].tv_usec = ut->mtime_ns / 1000; \
5185
0
        time = tv; \
5186
0
    } \
5274
0
    return futimes(fd, time);
5275
0
    }
5276
7
#endif
5277
7
}
5278
5279
    #define PATH_UTIME_HAVE_FD 1
5280
#else
5281
    #define PATH_UTIME_HAVE_FD 0
5282
#endif
5283
5284
#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
5285
#  define UTIME_HAVE_NOFOLLOW_SYMLINKS
5286
#endif
5287
5288
#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
5289
5290
static int
5291
utime_nofollow_symlinks(utime_t *ut, const char *path)
5292
10
{
5293
10
#ifdef HAVE_UTIMENSAT
5294
10
    if (HAVE_UTIMENSAT_RUNTIME) {
Line
Count
Source
176
10
#  define HAVE_UTIMENSAT_RUNTIME 1
  Branch (176:34): [Folded - Ignored]
5295
10
        UTIME_TO_TIMESPEC;
Line
Count
Source
5163
10
    struct timespec ts[2]; \
5164
10
    struct timespec *time; \
5165
10
    if (ut->now) \
  Branch (5165:9): [True: 2, False: 8]
5166
10
        time = NULL; \
5167
10
    else { \
5168
8
        ts[0].tv_sec = ut->atime_s; \
5169
8
        ts[0].tv_nsec = ut->atime_ns; \
5170
8
        ts[1].tv_sec = ut->mtime_s; \
5171
8
        ts[1].tv_nsec = ut->mtime_ns; \
5172
8
        time = ts; \
5173
8
    } \
5296
10
        return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
Line
Count
Source
904
10
#define DEFAULT_DIR_FD (int)AT_FDCWD
5297
10
    } else
5298
#ifndef HAVE_LUTIMES
5299
    {
5300
        /* Not sure if this can happen */
5301
        PyErr_SetString(
5302
            PyExc_RuntimeError,
5303
            "neither utimensat nor lutimes are supported"
5304
            " on this system");
5305
        return -1;
5306
    }
5307
#endif
5308
0
#endif
5309
5310
0
#ifdef HAVE_LUTIMES
5311
0
    {
5312
0
    UTIME_TO_TIMEVAL;
Line
Count
Source
5176
0
    struct timeval tv[2]; \
5177
0
    struct timeval *time; \
5178
0
    if (ut->now) \
  Branch (5178:9): [True: 0, False: 0]
5179
0
        time = NULL; \
5180
0
    else { \
5181
0
        tv[0].tv_sec = ut->atime_s; \
5182
0
        tv[0].tv_usec = ut->atime_ns / 1000; \
5183
0
        tv[1].tv_sec = ut->mtime_s; \
5184
0
        tv[1].tv_usec = ut->mtime_ns / 1000; \
5185
0
        time = tv; \
5186
0
    } \
5313
0
    return lutimes(path, time);
5314
0
    }
5315
10
#endif
5316
10
}
5317
5318
#endif
5319
5320
#ifndef MS_WINDOWS
5321
5322
static int
5323
utime_default(utime_t *ut, const char *path)
5324
8.98k
{
5325
#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5326
    if (HAVE_UTIMENSAT_RUNTIME) {
5327
        UTIME_TO_TIMESPEC;
5328
        return utimensat(DEFAULT_DIR_FD, path, time, 0);
5329
    } else {
5330
        UTIME_TO_TIMEVAL;
5331
        return utimes(path, time);
5332
    }
5333
#elif defined(HAVE_UTIMENSAT)
5334
8.98k
    UTIME_TO_TIMESPEC;
Line
Count
Source
5163
8.98k
    struct timespec ts[2]; \
5164
8.98k
    struct timespec *time; \
5165
8.98k
    if (ut->now) \
  Branch (5165:9): [True: 60, False: 8.92k]
5166
8.98k
        time = NULL; \
5167
8.98k
    else { \
5168
8.92k
        ts[0].tv_sec = ut->atime_s; \
5169
8.92k
        ts[0].tv_nsec = ut->atime_ns; \
5170
8.92k
        ts[1].tv_sec = ut->mtime_s; \
5171
8.92k
        ts[1].tv_nsec = ut->mtime_ns; \
5172
8.92k
        time = ts; \
5173
8.92k
    } \
5335
8.98k
    return utimensat(DEFAULT_DIR_FD, path, time, 0);
Line
Count
Source
904
8.98k
#define DEFAULT_DIR_FD (int)AT_FDCWD
5336
#elif defined(HAVE_UTIMES)
5337
    UTIME_TO_TIMEVAL;
5338
    return utimes(path, time);
5339
#elif defined(HAVE_UTIME_H)
5340
    UTIME_TO_UTIMBUF;
5341
    return utime(path, time);
5342
#else
5343
    UTIME_TO_TIME_T;
5344
    return utime(path, time);
5345
#endif
5346
8.98k
}
5347
5348
#endif
5349
5350
static int
5351
split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
5352
17.2k
{
5353
17.2k
    int result = 0;
5354
17.2k
    PyObject *divmod;
5355
17.2k
    divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
5356
17.2k
    if (!divmod)
  Branch (5356:9): [True: 0, False: 17.2k]
5357
0
        goto exit;
5358
17.2k
    if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
Line
Count
Source
27
17.2k
                 PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS)
Line
Count
Source
782
34.5k
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
    if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
Line
Count
Source
26
17.2k
#define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op))
Line
Count
Source
109
17.2k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
17.2k
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (5358:9): [True: 1, False: 17.2k]
  Branch (5358:35): [True: 2, False: 17.2k]
5359
3
        PyErr_Format(PyExc_TypeError,
5360
3
                     "%.200s.__divmod__() must return a 2-tuple, not %.200s",
5361
3
                     _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Line
Count
Source
138
3
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
3
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
3
#  define _Py_CAST(type, expr) ((type)(expr))
                     _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Line
Count
Source
138
3
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
3
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
3
#  define _Py_CAST(type, expr) ((type)(expr))
5362
3
        goto exit;
5363
3
    }
5364
17.2k
    *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
Line
Count
Source
28
17.2k
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)])
Line
Count
Source
18
17.2k
    (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op)))
Line
Count
Source
71
17.2k
#  define _Py_CAST(type, expr) ((type)(expr))
5365
17.2k
    if ((*s == -1) && PyErr_Occurred())
  Branch (5365:9): [True: 0, False: 17.2k]
  Branch (5365:23): [True: 0, False: 0]
5366
0
        goto exit;
5367
17.2k
    *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Line
Count
Source
28
17.2k
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)])
Line
Count
Source
18
17.2k
    (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op)))
Line
Count
Source
71
17.2k
#  define _Py_CAST(type, expr) ((type)(expr))
5368
17.2k
    if ((*ns == -1) && PyErr_Occurred())
  Branch (5368:9): [True: 0, False: 17.2k]
  Branch (5368:24): [True: 0, False: 0]
5369
0
        goto exit;
5370
5371
17.2k
    result = 1;
5372
17.2k
exit:
5373
17.2k
    Py_XDECREF(divmod);
Line
Count
Source
613
17.2k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
17.2k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
17.2k
#  define _Py_CAST(type, expr) ((type)(expr))
5374
17.2k
    return result;
5375
17.2k
}
5376
5377
5378
/*[clinic input]
5379
os.utime
5380
5381
    path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
5382
    times: object = None
5383
    *
5384
    ns: object = NULL
5385
    dir_fd: dir_fd(requires='futimensat') = None
5386
    follow_symlinks: bool=True
5387
5388
# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
5389
5390
Set the access and modified time of path.
5391
5392
path may always be specified as a string.
5393
On some platforms, path may also be specified as an open file descriptor.
5394
  If this functionality is unavailable, using it raises an exception.
5395
5396
If times is not None, it must be a tuple (atime, mtime);
5397
    atime and mtime should be expressed as float seconds since the epoch.
5398
If ns is specified, it must be a tuple (atime_ns, mtime_ns);
5399
    atime_ns and mtime_ns should be expressed as integer nanoseconds
5400
    since the epoch.
5401
If times is None and ns is unspecified, utime uses the current time.
5402
Specifying tuples for both times and ns is an error.
5403
5404
If dir_fd is not None, it should be a file descriptor open to a directory,
5405
  and path should be relative; path will then be relative to that directory.
5406
If follow_symlinks is False, and the last element of the path is a symbolic
5407
  link, utime will modify the symbolic link itself instead of the file the
5408
  link points to.
5409
It is an error to use dir_fd or follow_symlinks when specifying path
5410
  as an open file descriptor.
5411
dir_fd and follow_symlinks may not be available on your platform.
5412
  If they are unavailable, using them will raise a NotImplementedError.
5413
5414
[clinic start generated code]*/
5415
5416
static PyObject *
5417
os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
5418
              int dir_fd, int follow_symlinks)
5419
/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
5420
9.04k
{
5421
#ifdef MS_WINDOWS
5422
    HANDLE hFile;
5423
    FILETIME atime, mtime;
5424
#else
5425
9.04k
    int result;
5426
9.04k
#endif
5427
5428
9.04k
    utime_t utime;
5429
5430
9.04k
    memset(&utime, 0, sizeof(utime_t));
5431
5432
9.04k
    if (times != Py_None && ns) {
Line
Count
Source
654
18.0k
#define Py_None (&_Py_NoneStruct)
  Branch (5432:9): [True: 332, False: 8.70k]
  Branch (5432:29): [True: 4, False: 328]
5433
4
        PyErr_SetString(PyExc_ValueError,
5434
4
                     "utime: you may specify either 'times'"
5435
4
                     " or 'ns' but not both");
5436
4
        return NULL;
5437
4
    }
5438
5439
9.03k
    if (times != Py_None) {
Line
Count
Source
654
9.03k
#define Py_None (&_Py_NoneStruct)
  Branch (5439:9): [True: 328, False: 8.70k]
5440
328
        time_t a_sec, m_sec;
5441
328
        long a_nsec, m_nsec;
5442
328
        if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Line
Count
Source
28
328
#define PyTuple_CheckExact(op) Py_IS_TYPE((op), &PyTuple_Type)
Line
Count
Source
155
656
#  define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), (type))
Line
Count
Source
109
328
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
328
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (5442:13): [True: 2, False: 326]
  Branch (5442:43): [True: 2, False: 324]
5443
4
            PyErr_SetString(PyExc_TypeError,
5444
4
                         "utime: 'times' must be either"
5445
4
                         " a tuple of two ints or None");
5446
4
            return NULL;
5447
4
        }
5448
324
        utime.now = 0;
5449
324
        if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Line
Count
Source
28
324
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)])
Line
Count
Source
18
324
    (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op)))
Line
Count
Source
71
324
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (5449:13): [True: 8, False: 316]
5450
324
                                     &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
5451
324
            _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Line
Count
Source
28
316
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)])
Line
Count
Source
18
316
    (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op)))
Line
Count
Source
71
316
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (5451:13): [True: 5, False: 311]
5452
316
                                     &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
5453
13
            return NULL;
5454
13
        }
5455
311
        utime.atime_s = a_sec;
5456
311
        utime.atime_ns = a_nsec;
5457
311
        utime.mtime_s = m_sec;
5458
311
        utime.mtime_ns = m_nsec;
5459
311
    }
5460
8.70k
    else if (ns) {
  Branch (5460:14): [True: 8.64k, False: 67]
5461
8.64k
        if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Line
Count
Source
28
8.64k
#define PyTuple_CheckExact(op) Py_IS_TYPE((op), &PyTuple_Type)
Line
Count
Source
155
17.2k
#  define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), (type))
Line
Count
Source
109
8.64k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8.64k
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (5461:13): [True: 1, False: 8.64k]
  Branch (5461:40): [True: 2, False: 8.63k]
5462
3
            PyErr_SetString(PyExc_TypeError,
5463
3
                         "utime: 'ns' must be a tuple of two ints");
5464
3
            return NULL;
5465
3
        }
5466
8.63k
        utime.now = 0;
5467
8.63k
        if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Line
Count
Source
28
8.63k
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)])
Line
Count
Source
18
8.63k
    (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op)))
Line
Count
Source
71
8.63k
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (5467:13): [True: 3, False: 8.63k]
5468
8.63k
                                      &utime.atime_s, &utime.atime_ns) ||
5469
8.63k
            !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Line
Count
Source
28
8.63k
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)])
Line
Count
Source
18
8.63k
    (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op)))
Line
Count
Source
71
8.63k
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (5469:13): [True: 0, False: 8.63k]
5470
8.63k
                                       &utime.mtime_s, &utime.mtime_ns)) {
5471
3
            return NULL;
5472
3
        }
5473
8.63k
    }
5474
67
    else {
5475
        /* times and ns are both None/unspecified. use "now". */
5476
67
        utime.now = 1;
5477
67
    }
5478
5479
#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
5480
    if (follow_symlinks_specified("utime", follow_symlinks))
5481
        return NULL;
5482
#endif
5483
5484
9.01k
    if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
  Branch (5484:9): [True: 0, False: 9.01k]
5485
9.01k
        dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
  Branch (5485:9): [True: 0, False: 9.01k]
5486
9.01k
        fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
  Branch (5486:9): [True: 0, False: 9.01k]
5487
0
        return NULL;
5488
5489
#if !defined(HAVE_UTIMENSAT)
5490
    if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
5491
        PyErr_SetString(PyExc_ValueError,
5492
                     "utime: cannot use dir_fd and follow_symlinks "
5493
                     "together on this platform");
5494
        return NULL;
5495
    }
5496
#endif
5497
5498
9.01k
    if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
Line
Count
Source
654
378
#define Py_None (&_Py_NoneStruct)
  Branch (5498:9): [True: 0, False: 9.01k]
  Branch (5498:62): [True: 8.63k, False: 378]
5499
9.01k
                    dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
Line
Count
Source
904
9.01k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (5499:21): [True: 9.00k, False: 8]
5500
0
        return NULL;
5501
0
    }
5502
5503
#ifdef MS_WINDOWS
5504
    Py_BEGIN_ALLOW_THREADS
5505
    hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5506
                        NULL, OPEN_EXISTING,
5507
                        FILE_FLAG_BACKUP_SEMANTICS, NULL);
5508
    Py_END_ALLOW_THREADS
5509
    if (hFile == INVALID_HANDLE_VALUE) {
5510
        path_error(path);
5511
        return NULL;
5512
    }
5513
5514
    if (utime.now) {
5515
        GetSystemTimeAsFileTime(&mtime);
5516
        atime = mtime;
5517
    }
5518
    else {
5519
        _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5520
        _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
5521
    }
5522
    if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5523
        /* Avoid putting the file name into the error here,
5524
           as that may confuse the user into believing that
5525
           something is wrong with the file, when it also
5526
           could be the time stamp that gives a problem. */
5527
        PyErr_SetFromWindowsErr(0);
5528
        CloseHandle(hFile);
5529
        return NULL;
5530
    }
5531
    CloseHandle(hFile);
5532
#else /* MS_WINDOWS */
5533
9.01k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
9.01k
#define Py_BEGIN_ALLOW_THREADS { \
143
9.01k
                        PyThreadState *_save; \
144
9.01k
                        _save = PyEval_SaveThread();
5534
5535
9.01k
#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
5536
9.01k
    if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Line
Count
Source
904
11
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (5536:9): [True: 11, False: 9.00k]
  Branch (5536:31): [True: 10, False: 1]
5537
10
        result = utime_nofollow_symlinks(&utime, path->narrow);
5538
9.00k
    else
5539
9.00k
#endif
5540
5541
9.00k
#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
5542
9.00k
    if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
Line
Count
Source
904
9.00k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (5542:9): [True: 8, False: 8.99k]
  Branch (5542:39): [True: 0, False: 8.99k]
5543
8
        result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
5544
5545
8
    } else
5546
8.99k
#endif
5547
5548
8.99k
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
5549
8.99k
    if (path->fd != -1)
  Branch (5549:9): [True: 7, False: 8.98k]
5550
7
        result = utime_fd(&utime, path->fd);
5551
8.98k
    else
5552
8.98k
#endif
5553
5554
8.98k
    result = utime_default(&utime, path->narrow);
5555
5556
9.01k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
9.01k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
9.01k
                 }
5557
5558
#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5559
    /* See utime_dir_fd implementation */
5560
    if (result == -1 && errno == ENOSYS) {
5561
        argument_unavailable_error(NULL, "dir_fd");
5562
        return NULL;
5563
    }
5564
#endif
5565
5566
9.01k
    if (result < 0) {
  Branch (5566:9): [True: 49, False: 8.96k]
5567
        /* see previous comment about not putting filename in error here */
5568
49
        posix_error();
5569
49
        return NULL;
5570
49
    }
5571
5572
8.96k
#endif /* MS_WINDOWS */
5573
5574
9.01k
    Py_RETURN_NONE;
Line
Count
Source
661
8.96k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
8.96k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
8.96k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8.96k
#  define _Py_CAST(type, expr) ((type)(expr))
5575
9.01k
}
5576
5577
/* Process operations */
5578
5579
5580
/*[clinic input]
5581
os._exit
5582
5583
    status: int
5584
5585
Exit to the system with specified status, without normal exit processing.
5586
[clinic start generated code]*/
5587
5588
static PyObject *
5589
os__exit_impl(PyObject *module, int status)
5590
/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
5591
0
{
5592
0
    _exit(status);
5593
0
    return NULL; /* Make gcc -Wall happy */
5594
0
}
5595
5596
#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5597
#define EXECV_CHAR wchar_t
5598
#else
5599
456
#define EXECV_CHAR char
5600
#endif
5601
5602
#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
5603
static void
5604
free_string_array(EXECV_CHAR **array, Py_ssize_t count)
5605
225
{
5606
225
    Py_ssize_t i;
5607
6.39k
    for (i = 0; i < count; i++)
  Branch (5607:17): [True: 6.17k, False: 225]
5608
6.17k
        PyMem_Free(array[i]);
5609
225
    PyMem_Free(array);
5610
225
}
5611
5612
static int
5613
fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
5614
6.17k
{
5615
6.17k
    Py_ssize_t size;
5616
6.17k
    PyObject *ub;
5617
6.17k
    int result = 0;
5618
#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5619
    if (!PyUnicode_FSDecoder(o, &ub))
5620
        return 0;
5621
    *out = PyUnicode_AsWideCharString(ub, &size);
5622
    if (*out)
5623
        result = 1;
5624
#else
5625
6.17k
    if (!PyUnicode_FSConverter(o, &ub))
  Branch (5625:9): [True: 0, False: 6.17k]
5626
0
        return 0;
5627
6.17k
    size = PyBytes_GET_SIZE(ub);
Line
Count
Source
45
6.17k
#define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self))
Line
Count
Source
109
6.17k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
6.17k
#  define _Py_CAST(type, expr) ((type)(expr))
5628
6.17k
    *out = PyMem_Malloc(size + 1);
5629
6.17k
    if (*out) {
  Branch (5629:9): [True: 6.17k, False: 0]
5630
6.17k
        memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
Line
Count
Source
39
6.17k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
6.17k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
6.17k
#  define _Py_CAST(type, expr) ((type)(expr))
5631
6.17k
        result = 1;
5632
6.17k
    } else
5633
0
        PyErr_NoMemory();
5634
6.17k
#endif
5635
6.17k
    Py_DECREF(ub);
Line
Count
Source
548
6.17k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
6.17k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
6.17k
#  define _Py_CAST(type, expr) ((type)(expr))
5636
6.17k
    return result;
5637
6.17k
}
5638
#endif
5639
5640
#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
5641
static EXECV_CHAR**
5642
parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5643
92
{
5644
92
    Py_ssize_t i, pos, envc;
5645
92
    PyObject *keys=NULL, *vals=NULL;
5646
92
    PyObject *key, *val, *key2, *val2, *keyval;
5647
92
    EXECV_CHAR **envlist;
Line
Count
Source
5599
92
#define EXECV_CHAR char
5648
5649
92
    i = PyMapping_Size(env);
5650
92
    if (i < 0)
  Branch (5650:9): [True: 0, False: 92]
5651
0
        return NULL;
5652
92
    envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Line
Count
Source
86
92
#define PyMem_NEW(type, n)        PyMem_New(type, (n))
Line
Count
Source
68
92
  ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL :      \
Line
Count
Source
180
92
#   define PY_SSIZE_T_MAX SSIZE_MAX
  Branch (68:5): [True: 0, False: 92]
69
92
        ( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
5653
92
    if (envlist == NULL) {
  Branch (5653:9): [True: 0, False: 92]
5654
0
        PyErr_NoMemory();
5655
0
        return NULL;
5656
0
    }
5657
92
    envc = 0;
5658
92
    keys = PyMapping_Keys(env);
5659
92
    if (!keys)
  Branch (5659:9): [True: 0, False: 92]
5660
0
        goto error;
5661
92
    vals = PyMapping_Values(env);
5662
92
    if (!vals)
  Branch (5662:9): [True: 0, False: 92]
5663
0
        goto error;
5664
92
    if (!PyList_Check(keys) || !PyList_Check(vals)) {
Line
Count
Source
25
92
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS)
Line
Count
Source
782
184
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
    if (!PyList_Check(keys) || !PyList_Check(vals)) {
Line
Count
Source
25
92
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS)
Line
Count
Source
782
92
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (5664:9): [True: 0, False: 92]
  Branch (5664:32): [True: 0, False: 92]
5665
0
        PyErr_Format(PyExc_TypeError,
5666
0
                     "env.keys() or env.values() is not a list");
5667
0
        goto error;
5668
0
    }
5669
5670
5.89k
    for (pos = 0; pos < i; pos++) {
  Branch (5670:19): [True: 5.80k, False: 89]
5671
5.80k
        key = PyList_GetItem(keys, pos);
5672
5.80k
        val = PyList_GetItem(vals, pos);
5673
5.80k
        if (!key || !val)
  Branch (5673:13): [True: 0, False: 5.80k]
  Branch (5673:21): [True: 0, False: 5.80k]
5674
0
            goto error;
5675
5676
#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5677
        if (!PyUnicode_FSDecoder(key, &key2))
5678
            goto error;
5679
        if (!PyUnicode_FSDecoder(val, &val2)) {
5680
            Py_DECREF(key2);
5681
            goto error;
5682
        }
5683
        /* Search from index 1 because on Windows starting '=' is allowed for
5684
           defining hidden environment variables. */
5685
        if (PyUnicode_GET_LENGTH(key2) == 0 ||
5686
            PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5687
        {
5688
            PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
5689
            Py_DECREF(key2);
5690
            Py_DECREF(val2);
5691
            goto error;
5692
        }
5693
        keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5694
#else
5695
5.80k
        if (!PyUnicode_FSConverter(key, &key2))
  Branch (5695:13): [True: 1, False: 5.80k]
5696
1
            goto error;
5697
5.80k
        if (!PyUnicode_FSConverter(val, &val2)) {
  Branch (5697:13): [True: 1, False: 5.79k]
5698
1
            Py_DECREF(key2);
Line
Count
Source
548
1
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
5699
1
            goto error;
5700
1
        }
5701
5.79k
        if (PyBytes_GET_SIZE(key2) == 0 ||
Line
Count
Source
45
5.79k
#define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self))
Line
Count
Source
109
5.79k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5.79k
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (5701:13): [True: 0, False: 5.79k]
5702
5.79k
            strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
Line
Count
Source
39
5.79k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
5.79k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5.79k
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (5702:13): [True: 1, False: 5.79k]
5703
1
        {
5704
1
            PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
5705
1
            Py_DECREF(key2);
Line
Count
Source
548
1
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
5706
1
            Py_DECREF(val2);
Line
Count
Source
548
1
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
5707
1
            goto error;
5708
1
        }
5709
5.79k
        keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
Line
Count
Source
39
5.79k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
5.79k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5.79k
#  define _Py_CAST(type, expr) ((type)(expr))
5710
5.79k
                                             PyBytes_AS_STRING(val2));
Line
Count
Source
39
5.79k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
5.79k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5.79k
#  define _Py_CAST(type, expr) ((type)(expr))
5711
5.79k
#endif
5712
5.79k
        Py_DECREF(key2);
Line
Count
Source
548
5.79k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
5.79k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5.79k
#  define _Py_CAST(type, expr) ((type)(expr))
5713
5.79k
        Py_DECREF(val2);
Line
Count
Source
548
5.79k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
5.79k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5.79k
#  define _Py_CAST(type, expr) ((type)(expr))
5714
5.79k
        if (!keyval)
  Branch (5714:13): [True: 0, False: 5.79k]
5715
0
            goto error;
5716
5717
5.79k
        if (!fsconvert_strdup(keyval, &envlist[envc++])) {
  Branch (5717:13): [True: 0, False: 5.79k]
5718
0
            Py_DECREF(keyval);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
5719
0
            goto error;
5720
0
        }
5721
5722
5.79k
        Py_DECREF(keyval);
Line
Count
Source
548
5.79k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
5.79k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5.79k
#  define _Py_CAST(type, expr) ((type)(expr))
5723
5.79k
    }
5724
89
    Py_DECREF(vals);
Line
Count
Source
548
89
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
89
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
89
#  define _Py_CAST(type, expr) ((type)(expr))
5725
89
    Py_DECREF(keys);
Line
Count
Source
548
89
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
89
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
89
#  define _Py_CAST(type, expr) ((type)(expr))
5726
5727
89
    envlist[envc] = 0;
5728
89
    *envc_ptr = envc;
5729
89
    return envlist;
5730
5731
3
error:
5732
3
    Py_XDECREF(keys);
Line
Count
Source
613
3
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
3
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
3
#  define _Py_CAST(type, expr) ((type)(expr))
5733
3
    Py_XDECREF(vals);
Line
Count
Source
613
3
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
3
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
3
#  define _Py_CAST(type, expr) ((type)(expr))
5734
3
    free_string_array(envlist, envc);
5735
3
    return NULL;
5736
92
}
5737
5738
static EXECV_CHAR**
5739
parse_arglist(PyObject* argv, Py_ssize_t *argc)
5740
133
{
5741
133
    int i;
5742
133
    EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Line
Count
Source
5599
133
#define EXECV_CHAR char
    EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Line
Count
Source
86
133
#define PyMem_NEW(type, n)        PyMem_New(type, (n))
Line
Count
Source
68
133
  ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL :      \
Line
Count
Source
180
133
#   define PY_SSIZE_T_MAX SSIZE_MAX
  Branch (68:5): [True: 0, False: 133]
69
133
        ( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
5743
133
    if (argvlist == NULL) {
  Branch (5743:9): [True: 0, False: 133]
5744
0
        PyErr_NoMemory();
5745
0
        return NULL;
5746
0
    }
5747
506
    for (i = 0; i < *argc; i++) {
  Branch (5747:17): [True: 373, False: 133]
5748
373
        PyObject* item = PySequence_ITEM(argv, i);
Line
Count
Source
179
373
    ( Py_TYPE(o)->tp_as_sequence->sq_item((o), (i)) )
Line
Count
Source
138
373
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
373
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
373
#  define _Py_CAST(type, expr) ((type)(expr))
5749
373
        if (item == NULL)
  Branch (5749:13): [True: 0, False: 373]
5750
0
            goto fail;
5751
373
        if (!fsconvert_strdup(item, &argvlist[i])) {
  Branch (5751:13): [True: 0, False: 373]
5752
0
            Py_DECREF(item);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
5753
0
            goto fail;
5754
0
        }
5755
373
        Py_DECREF(item);
Line
Count
Source
548
373
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
373
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
373
#  define _Py_CAST(type, expr) ((type)(expr))
5756
373
    }
5757
133
    argvlist[*argc] = NULL;
5758
133
    return argvlist;
5759
0
fail:
5760
0
    *argc = i;
5761
0
    free_string_array(argvlist, *argc);
5762
0
    return NULL;
5763
133
}
5764
5765
#endif
5766
5767
5768
#ifdef HAVE_EXECV
5769
/*[clinic input]
5770
os.execv
5771
5772
    path: path_t
5773
        Path of executable file.
5774
    argv: object
5775
        Tuple or list of strings.
5776
    /
5777
5778
Execute an executable path with arguments, replacing current process.
5779
[clinic start generated code]*/
5780
5781
static PyObject *
5782
os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5783
/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
5784
43
{
5785
43
    EXECV_CHAR **argvlist;
Line
Count
Source
5599
43
#define EXECV_CHAR char
5786
43
    Py_ssize_t argc;
5787
5788
    /* execv has two arguments: (path, argv), where
5789
       argv is a list or tuple of strings. */
5790
5791
43
    if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Line
Count
Source
25
43
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS)
Line
Count
Source
782
86
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
    if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Line
Count
Source
27
2
                 PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS)
Line
Count
Source
782
2
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (5791:9): [True: 2, False: 41]
  Branch (5791:32): [True: 0, False: 2]
5792
0
        PyErr_SetString(PyExc_TypeError,
5793
0
                        "execv() arg 2 must be a tuple or list");
5794
0
        return NULL;
5795
0
    }
5796
43
    argc = PySequence_Size(argv);
5797
43
    if (argc < 1) {
  Branch (5797:9): [True: 3, False: 40]
5798
3
        PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5799
3
        return NULL;
5800
3
    }
5801
5802
40
    argvlist = parse_arglist(argv, &argc);
5803
40
    if (argvlist == NULL) {
  Branch (5803:9): [True: 0, False: 40]
5804
0
        return NULL;
5805
0
    }
5806
40
    if (!argvlist[0][0]) {
  Branch (5806:9): [True: 2, False: 38]
5807
2
        PyErr_SetString(PyExc_ValueError,
5808
2
            "execv() arg 2 first element cannot be empty");
5809
2
        free_string_array(argvlist, argc);
5810
2
        return NULL;
5811
2
    }
5812
5813
38
    if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Line
Count
Source
654
38
#define Py_None (&_Py_NoneStruct)
  Branch (5813:9): [True: 0, False: 38]
5814
0
        free_string_array(argvlist, argc);
5815
0
        return NULL;
5816
0
    }
5817
5818
38
    _Py_BEGIN_SUPPRESS_IPH
5819
#ifdef HAVE_WEXECV
5820
    _wexecv(path->wide, argvlist);
5821
#else
5822
38
    execv(path->narrow, argvlist);
5823
38
#endif
5824
38
    _Py_END_SUPPRESS_IPH
5825
5826
    /* If we get here it's definitely an error */
5827
5828
38
    free_string_array(argvlist, argc);
5829
38
    return posix_error();
5830
38
}
5831
5832
5833
/*[clinic input]
5834
os.execve
5835
5836
    path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5837
        Path of executable file.
5838
    argv: object
5839
        Tuple or list of strings.
5840
    env: object
5841
        Dictionary of strings mapping to strings.
5842
5843
Execute an executable path with arguments, replacing current process.
5844
[clinic start generated code]*/
5845
5846
static PyObject *
5847
os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5848
/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
5849
5
{
5850
5
    EXECV_CHAR **argvlist = NULL;
Line
Count
Source
5599
5
#define EXECV_CHAR char
5851
5
    EXECV_CHAR **envlist;
Line
Count
Source
5599
5
#define EXECV_CHAR char
5852
5
    Py_ssize_t argc, envc;
5853
5854
    /* execve has three arguments: (path, argv, env), where
5855
       argv is a list or tuple of strings and env is a dictionary
5856
       like posix.environ. */
5857
5858
5
    if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Line
Count
Source
25
5
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS)
Line
Count
Source
782
10
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
    if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Line
Count
Source
27
0
                 PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS)
Line
Count
Source
782
0
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (5858:9): [True: 0, False: 5]
  Branch (5858:32): [True: 0, False: 0]
5859
0
        PyErr_SetString(PyExc_TypeError,
5860
0
                        "execve: argv must be a tuple or list");
5861
0
        goto fail_0;
5862
0
    }
5863
5
    argc = PySequence_Size(argv);
5864
5
    if (argc < 1) {
  Branch (5864:9): [True: 1, False: 4]
5865
1
        PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5866
1
        return NULL;
5867
1
    }
5868
5869
4
    if (!PyMapping_Check(env)) {
  Branch (5869:9): [True: 0, False: 4]
5870
0
        PyErr_SetString(PyExc_TypeError,
5871
0
                        "execve: environment must be a mapping object");
5872
0
        goto fail_0;
5873
0
    }
5874
5875
4
    argvlist = parse_arglist(argv, &argc);
5876
4
    if (argvlist == NULL) {
  Branch (5876:9): [True: 0, False: 4]
5877
0
        goto fail_0;
5878
0
    }
5879
4
    if (!argvlist[0][0]) {
  Branch (5879:9): [True: 1, False: 3]
5880
1
        PyErr_SetString(PyExc_ValueError,
5881
1
            "execve: argv first element cannot be empty");
5882
1
        goto fail_0;
5883
1
    }
5884
5885
3
    envlist = parse_envlist(env, &envc);
5886
3
    if (envlist == NULL)
  Branch (5886:9): [True: 3, False: 0]
5887
3
        goto fail_0;
5888
5889
0
    if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
  Branch (5889:9): [True: 0, False: 0]
5890
0
        goto fail_1;
5891
0
    }
5892
5893
0
    _Py_BEGIN_SUPPRESS_IPH
5894
0
#ifdef HAVE_FEXECVE
5895
0
    if (path->fd > -1)
  Branch (5895:9): [True: 0, False: 0]
5896
0
        fexecve(path->fd, argvlist, envlist);
5897
0
    else
5898
0
#endif
5899
#ifdef HAVE_WEXECV
5900
        _wexecve(path->wide, argvlist, envlist);
5901
#else
5902
0
        execve(path->narrow, argvlist, envlist);
5903
0
#endif
5904
0
    _Py_END_SUPPRESS_IPH
5905
5906
    /* If we get here it's definitely an error */
5907
5908
0
    posix_path_error(path);
5909
0
  fail_1:
5910
0
    free_string_array(envlist, envc);
5911
4
  fail_0:
5912
4
    if (argvlist)
  Branch (5912:9): [True: 4, False: 0]
5913
4
        free_string_array(argvlist, argc);
5914
4
    return NULL;
5915
0
}
5916
5917
#endif /* HAVE_EXECV */
5918
5919
#ifdef HAVE_POSIX_SPAWN
5920
5921
enum posix_spawn_file_actions_identifier {
5922
    POSIX_SPAWN_OPEN,
5923
    POSIX_SPAWN_CLOSE,
5924
    POSIX_SPAWN_DUP2
5925
};
5926
5927
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
5928
static int
5929
convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
5930
#endif
5931
5932
static int
5933
parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
5934
                        int resetids, int setsid, PyObject *setsigmask,
5935
                        PyObject *setsigdef, PyObject *scheduler,
5936
                        posix_spawnattr_t *attrp)
5937
73
{
5938
73
    long all_flags = 0;
5939
5940
73
    errno = posix_spawnattr_init(attrp);
5941
73
    if (errno) {
5942
0
        posix_error();
5943
0
        return -1;
5944
0
    }
5945
5946
73
    if (setpgroup) {
  Branch (5946:9): [True: 4, False: 69]
5947
4
        pid_t pgid = PyLong_AsPid(setpgroup);
Line
Count
Source
37
4
#define PyLong_AsPid PyLong_AsLong
5948
4
        if (pgid == (pid_t)-1 && PyErr_Occurred()) {
  Branch (5948:13): [True: 2, False: 2]
  Branch (5948:34): [True: 2, False: 0]
5949
2
            goto fail;
5950
2
        }
5951
2
        errno = posix_spawnattr_setpgroup(attrp, pgid);
5952
2
        if (errno) {
5953
0
            posix_error();
5954
0
            goto fail;
5955
0
        }
5956
2
        all_flags |= POSIX_SPAWN_SETPGROUP;
5957
2
    }
5958
5959
71
    if (resetids) {
  Branch (5959:9): [True: 2, False: 69]
5960
2
        all_flags |= POSIX_SPAWN_RESETIDS;
5961
2
    }
5962
5963
71
    if (setsid) {
  Branch (5963:9): [True: 2, False: 69]
5964
#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5965
        if (HAVE_POSIX_SPAWN_SETSID_RUNTIME) {
5966
#endif
5967
2
#ifdef POSIX_SPAWN_SETSID
5968
2
        all_flags |= POSIX_SPAWN_SETSID;
5969
#elif defined(POSIX_SPAWN_SETSID_NP)
5970
        all_flags |= POSIX_SPAWN_SETSID_NP;
5971
#else
5972
        argument_unavailable_error(func_name, "setsid");
5973
        return -1;
5974
#endif
5975
5976
#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5977
        } else {
5978
            argument_unavailable_error(func_name, "setsid");
5979
            return -1;
5980
        }
5981
#endif /* HAVE_POSIX_SPAWN_SETSID_RUNTIME */
5982
5983
2
    }
5984
5985
71
#ifdef HAVE_SIGSET_T
5986
71
   if (setsigmask) {
  Branch (5986:8): [True: 8, False: 63]
5987
8
        sigset_t set;
5988
8
        if (!_Py_Sigset_Converter(setsigmask, &set)) {
  Branch (5988:13): [True: 6, False: 2]
5989
6
            goto fail;
5990
6
        }
5991
2
        errno = posix_spawnattr_setsigmask(attrp, &set);
5992
2
        if (errno) {
5993
0
            posix_error();
5994
0
            goto fail;
5995
0
        }
5996
2
        all_flags |= POSIX_SPAWN_SETSIGMASK;
5997
2
    }
5998
5999
65
    if (setsigdef) {
  Branch (5999:9): [True: 33, False: 32]
6000
33
        sigset_t set;
6001
33
        if (!_Py_Sigset_Converter(setsigdef, &set)) {
  Branch (6001:13): [True: 6, False: 27]
6002
6
            goto fail;
6003
6
        }
6004
27
        errno = posix_spawnattr_setsigdefault(attrp, &set);
6005
27
        if (errno) {
6006
0
            posix_error();
6007
0
            goto fail;
6008
0
        }
6009
27
        all_flags |= POSIX_SPAWN_SETSIGDEF;
6010
27
    }
6011
#else
6012
    if (setsigmask || setsigdef) {
6013
        PyErr_SetString(PyExc_NotImplementedError,
6014
                        "sigset is not supported on this platform");
6015
        goto fail;
6016
    }
6017
#endif
6018
6019
59
    if (scheduler) {
  Branch (6019:9): [True: 4, False: 55]
6020
4
#ifdef POSIX_SPAWN_SETSCHEDULER
6021
4
        PyObject *py_schedpolicy;
6022
4
        PyObject *schedparam_obj;
6023
4
        struct sched_param schedparam;
6024
6025
4
        if (!PyArg_ParseTuple(scheduler, "OO"
Line
Count
Source
16
4
#define PyArg_ParseTuple                _PyArg_ParseTuple_SizeT
  Branch (6025:13): [True: 0, False: 4]
6026
4
                        ";A scheduler tuple must have two elements",
6027
4
                        &py_schedpolicy, &schedparam_obj)) {
6028
0
            goto fail;
6029
0
        }
6030
4
        if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
  Branch (6030:13): [True: 0, False: 4]
6031
0
            goto fail;
6032
0
        }
6033
4
        if (py_schedpolicy != Py_None) {
Line
Count
Source
654
4
#define Py_None (&_Py_NoneStruct)
  Branch (6033:13): [True: 2, False: 2]
6034
2
            int schedpolicy = _PyLong_AsInt(py_schedpolicy);
6035
6036
2
            if (schedpolicy == -1 && PyErr_Occurred()) {
  Branch (6036:17): [True: 0, False: 2]
  Branch (6036:38): [True: 0, False: 0]
6037
0
                goto fail;
6038
0
            }
6039
2
            errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
6040
2
            if (errno) {
6041
0
                posix_error();
6042
0
                goto fail;
6043
0
            }
6044
2
            all_flags |= POSIX_SPAWN_SETSCHEDULER;
6045
2
        }
6046
4
        errno = posix_spawnattr_setschedparam(attrp, &schedparam);
6047
4
        if (errno) {
6048
0
            posix_error();
6049
0
            goto fail;
6050
0
        }
6051
4
        all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
6052
#else
6053
        PyErr_SetString(PyExc_NotImplementedError,
6054
                "The scheduler option is not supported in this system.");
6055
        goto fail;
6056
#endif
6057
4
    }
6058
6059
59
    errno = posix_spawnattr_setflags(attrp, all_flags);
6060
59
    if (errno) {
6061
0
        posix_error();
6062
0
        goto fail;
6063
0
    }
6064
6065
59
    return 0;
6066
6067
14
fail:
6068
14
    (void)posix_spawnattr_destroy(attrp);
6069
14
    return -1;
6070
59
}
6071
6072
static int
6073
parse_file_actions(PyObject *file_actions,
6074
                   posix_spawn_file_actions_t *file_actionsp,
6075
                   PyObject *temp_buffer)
6076
51
{
6077
51
    PyObject *seq;
6078
51
    PyObject *file_action = NULL;
6079
51
    PyObject *tag_obj;
6080
6081
51
    seq = PySequence_Fast(file_actions,
6082
51
                          "file_actions must be a sequence or None");
6083
51
    if (seq == NULL) {
  Branch (6083:9): [True: 0, False: 51]
6084
0
        return -1;
6085
0
    }
6086
6087
51
    errno = posix_spawn_file_actions_init(file_actionsp);
6088
51
    if (errno) {
6089
0
        posix_error();
6090
0
        Py_DECREF(seq);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
6091
0
        return -1;
6092
0
    }
6093
6094
172
    for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Line
Count
Source
720
172
    (PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o))
Line
Count
Source
25
172
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS)
Line
Count
Source
782
172
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (782:41): [True: 172, False: 0]
    (PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o))
Line
Count
Source
37
172
#define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op))
Line
Count
Source
109
172
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
172
#  define _Py_CAST(type, expr) ((type)(expr))
    (PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o))
Line
Count
Source
26
0
#define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (6094:28): [True: 137, False: 35]
6095
137
        file_action = PySequence_Fast_GET_ITEM(seq, i);
Line
Count
Source
725
137
     (PyList_Check(o) ? PyList_GET_ITEM((o), (i)) : PyTuple_GET_ITEM((o), (i)))
Line
Count
Source
25
137
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS)
Line
Count
Source
782
137
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (782:41): [True: 137, False: 0]
     (PyList_Check(o) ? PyList_GET_ITEM((o), (i)) : PyTuple_GET_ITEM((o), (i)))
Line
Count
Source
39
137
#define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[(index)])
Line
Count
Source
29
137
    (assert(PyList_Check(op)), _Py_CAST(PyListObject*, (op)))
Line
Count
Source
71
137
#  define _Py_CAST(type, expr) ((type)(expr))
     (PyList_Check(o) ? PyList_GET_ITEM((o), (i)) : PyTuple_GET_ITEM((o), (i)))
Line
Count
Source
28
0
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)])
Line
Count
Source
18
0
    (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op)))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
6096
137
        Py_INCREF(file_action);
Line
Count
Source
512
137
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
137
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
137
#  define _Py_CAST(type, expr) ((type)(expr))
6097
137
        if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
Line
Count
Source
27
137
                 PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS)
Line
Count
Source
782
274
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
        if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
Line
Count
Source
26
135
#define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op))
Line
Count
Source
109
135
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
135
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (6097:13): [True: 2, False: 135]
  Branch (6097:44): [True: 2, False: 133]
6098
4
            PyErr_SetString(PyExc_TypeError,
6099
4
                "Each file_actions element must be a non-empty tuple");
6100
4
            goto fail;
6101
4
        }
6102
133
        long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
Line
Count
Source
28
133
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)])
Line
Count
Source
18
133
    (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op)))
Line
Count
Source
71
133
#  define _Py_CAST(type, expr) ((type)(expr))
6103
133
        if (tag == -1 && PyErr_Occurred()) {
  Branch (6103:13): [True: 2, False: 131]
  Branch (6103:26): [True: 2, False: 0]
6104
2
            goto fail;
6105
2
        }
6106
6107
        /* Populate the file_actions object */
6108
131
        switch (tag) {
6109
6
            case POSIX_SPAWN_OPEN: {
  Branch (6109:13): [True: 6, False: 125]
6110
6
                int fd, oflag;
6111
6
                PyObject *path;
6112
6
                unsigned long mode;
6113
6
                if (!PyArg_ParseTuple(file_action, "OiO&ik"
Line
Count
Source
16
6
#define PyArg_ParseTuple                _PyArg_ParseTuple_SizeT
  Branch (6113:21): [True: 2, False: 4]
6114
6
                        ";A open file_action tuple must have 5 elements",
6115
6
                        &tag_obj, &fd, PyUnicode_FSConverter, &path,
6116
6
                        &oflag, &mode))
6117
2
                {
6118
2
                    goto fail;
6119
2
                }
6120
4
                if (PyList_Append(temp_buffer, path)) {
  Branch (6120:21): [True: 0, False: 4]
6121
0
                    Py_DECREF(path);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
6122
0
                    goto fail;
6123
0
                }
6124
4
                errno = posix_spawn_file_actions_addopen(file_actionsp,
6125
4
                        fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Line
Count
Source
39
4
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
4
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
4
#  define _Py_CAST(type, expr) ((type)(expr))
6126
4
                Py_DECREF(path);
Line
Count
Source
548
4
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
4
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
4
#  define _Py_CAST(type, expr) ((type)(expr))
6127
4
                if (errno) {
6128
0
                    posix_error();
6129
0
                    goto fail;
6130
0
                }
6131
4
                break;
6132
4
            }
6133
50
            case POSIX_SPAWN_CLOSE: {
  Branch (6133:13): [True: 50, False: 81]
6134
50
                int fd;
6135
50
                if (!PyArg_ParseTuple(file_action, "Oi"
Line
Count
Source
16
50
#define PyArg_ParseTuple                _PyArg_ParseTuple_SizeT
  Branch (6135:21): [True: 6, False: 44]
6136
50
                        ";A close file_action tuple must have 2 elements",
6137
50
                        &tag_obj, &fd))
6138
6
                {
6139
6
                    goto fail;
6140
6
                }
6141
44
                errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
6142
44
                if (errno) {
6143
0
                    posix_error();
6144
0
                    goto fail;
6145
0
                }
6146
44
                break;
6147
44
            }
6148
73
            case POSIX_SPAWN_DUP2: {
  Branch (6148:13): [True: 73, False: 58]
6149
73
                int fd1, fd2;
6150
73
                if (!PyArg_ParseTuple(file_action, "Oii"
Line
Count
Source
16
73
#define PyArg_ParseTuple                _PyArg_ParseTuple_SizeT
  Branch (6150:21): [True: 0, False: 73]
6151
73
                        ";A dup2 file_action tuple must have 3 elements",
6152
73
                        &tag_obj, &fd1, &fd2))
6153
0
                {
6154
0
                    goto fail;
6155
0
                }
6156
73
                errno = posix_spawn_file_actions_adddup2(file_actionsp,
6157
73
                                                         fd1, fd2);
6158
73
                if (errno) {
6159
0
                    posix_error();
6160
0
                    goto fail;
6161
0
                }
6162
73
                break;
6163
73
            }
6164
73
            default: {
  Branch (6164:13): [True: 2, False: 129]
6165
2
                PyErr_SetString(PyExc_TypeError,
6166
2
                                "Unknown file_actions identifier");
6167
2
                goto fail;
6168
73
            }
6169
131
        }
6170
121
        Py_DECREF(file_action);
Line
Count
Source
548
121
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
121
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
121
#  define _Py_CAST(type, expr) ((type)(expr))
6171
121
    }
6172
6173
35
    Py_DECREF(seq);
Line
Count
Source
548
35
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
35
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
35
#  define _Py_CAST(type, expr) ((type)(expr))
6174
35
    return 0;
6175
6176
16
fail:
6177
16
    Py_DECREF(seq);
Line
Count
Source
548
16
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
16
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
16
#  define _Py_CAST(type, expr) ((type)(expr))
6178
16
    Py_DECREF(file_action);
Line
Count
Source
548
16
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
16
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
16
#  define _Py_CAST(type, expr) ((type)(expr))
6179
16
    (void)posix_spawn_file_actions_destroy(file_actionsp);
6180
16
    return -1;
6181
51
}
6182
6183
6184
static PyObject *
6185
py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
6186
               PyObject *env, PyObject *file_actions,
6187
               PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
6188
               PyObject *setsigdef, PyObject *scheduler)
6189
89
{
6190
89
    const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
  Branch (6190:29): [True: 32, False: 57]
6191
89
    EXECV_CHAR **argvlist = NULL;
Line
Count
Source
5599
89
#define EXECV_CHAR char
6192
89
    EXECV_CHAR **envlist = NULL;
Line
Count
Source
5599
89
#define EXECV_CHAR char
6193
89
    posix_spawn_file_actions_t file_actions_buf;
6194
89
    posix_spawn_file_actions_t *file_actionsp = NULL;
6195
89
    posix_spawnattr_t attr;
6196
89
    posix_spawnattr_t *attrp = NULL;
6197
89
    Py_ssize_t argc, envc;
6198
89
    PyObject *result = NULL;
6199
89
    PyObject *temp_buffer = NULL;
6200
89
    pid_t pid;
6201
89
    int err_code;
6202
6203
    /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
6204
       argv is a list or tuple of strings and env is a dictionary
6205
       like posix.environ. */
6206
6207
89
    if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Line
Count
Source
25
89
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS)
Line
Count
Source
782
178
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
    if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Line
Count
Source
27
32
                 PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS)
Line
Count
Source
782
32
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (6207:9): [True: 32, False: 57]
  Branch (6207:32): [True: 0, False: 32]
6208
0
        PyErr_Format(PyExc_TypeError,
6209
0
                     "%s: argv must be a tuple or list", func_name);
6210
0
        goto exit;
6211
0
    }
6212
89
    argc = PySequence_Size(argv);
6213
89
    if (argc < 1) {
  Branch (6213:9): [True: 0, False: 89]
6214
0
        PyErr_Format(PyExc_ValueError,
6215
0
                     "%s: argv must not be empty", func_name);
6216
0
        return NULL;
6217
0
    }
6218
6219
89
    if (!PyMapping_Check(env)) {
  Branch (6219:9): [True: 0, False: 89]
6220
0
        PyErr_Format(PyExc_TypeError,
6221
0
                     "%s: environment must be a mapping object", func_name);
6222
0
        goto exit;
6223
0
    }
6224
6225
89
    argvlist = parse_arglist(argv, &argc);
6226
89
    if (argvlist == NULL) {
  Branch (6226:9): [True: 0, False: 89]
6227
0
        goto exit;
6228
0
    }
6229
89
    if (!argvlist[0][0]) {
  Branch (6229:9): [True: 0, False: 89]
6230
0
        PyErr_Format(PyExc_ValueError,
6231
0
                     "%s: argv first element cannot be empty", func_name);
6232
0
        goto exit;
6233
0
    }
6234
6235
89
    envlist = parse_envlist(env, &envc);
6236
89
    if (envlist == NULL) {
  Branch (6236:9): [True: 0, False: 89]
6237
0
        goto exit;
6238
0
    }
6239
6240
89
    if (file_actions != NULL && file_actions != Py_None) {
Line
Count
Source
654
53
#define Py_None (&_Py_NoneStruct)
  Branch (6240:9): [True: 53, False: 36]
  Branch (6240:33): [True: 51, False: 2]
6241
        /* There is a bug in old versions of glibc that makes some of the
6242
         * helper functions for manipulating file actions not copy the provided
6243
         * buffers. The problem is that posix_spawn_file_actions_addopen does not
6244
         * copy the value of path for some old versions of glibc (<2.20).
6245
         * The use of temp_buffer here is a workaround that keeps the
6246
         * python objects that own the buffers alive until posix_spawn gets called.
6247
         * Check https://bugs.python.org/issue33630 and
6248
         * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
6249
51
        temp_buffer = PyList_New(0);
6250
51
        if (!temp_buffer) {
  Branch (6250:13): [True: 0, False: 51]
6251
0
            goto exit;
6252
0
        }
6253
51
        if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
  Branch (6253:13): [True: 16, False: 35]
6254
16
            goto exit;
6255
16
        }
6256
35
        file_actionsp = &file_actions_buf;
6257
35
    }
6258
6259
73
    if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
  Branch (6259:9): [True: 14, False: 59]
6260
73
                                setsigmask, setsigdef, scheduler, &attr)) {
6261
14
        goto exit;
6262
14
    }
6263
59
    attrp = &attr;
6264
6265
59
    if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
  Branch (6265:9): [True: 0, False: 59]
6266
0
        goto exit;
6267
0
    }
6268
6269
59
    _Py_BEGIN_SUPPRESS_IPH
6270
59
#ifdef HAVE_POSIX_SPAWNP
6271
59
    if (use_posix_spawnp) {
  Branch (6271:9): [True: 17, False: 42]
6272
17
        err_code = posix_spawnp(&pid, path->narrow,
6273
17
                                file_actionsp, attrp, argvlist, envlist);
6274
17
    }
6275
42
    else
6276
42
#endif /* HAVE_POSIX_SPAWNP */
6277
42
    {
6278
42
        err_code = posix_spawn(&pid, path->narrow,
6279
42
                               file_actionsp, attrp, argvlist, envlist);
6280
42
    }
6281
59
    _Py_END_SUPPRESS_IPH
6282
6283
59
    if (err_code) {
  Branch (6283:9): [True: 2, False: 57]
6284
2
        errno = err_code;
6285
2
        PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
6286
2
        goto exit;
6287
2
    }
6288
#ifdef _Py_MEMORY_SANITIZER
6289
    __msan_unpoison(&pid, sizeof(pid));
6290
#endif
6291
57
    result = PyLong_FromPid(pid);
Line
Count
Source
36
57
#define PyLong_FromPid PyLong_FromLong
6292
6293
89
exit:
6294
89
    if (file_actionsp) {
  Branch (6294:9): [True: 35, False: 54]
6295
35
        (void)posix_spawn_file_actions_destroy(file_actionsp);
6296
35
    }
6297
89
    if (attrp) {
  Branch (6297:9): [True: 59, False: 30]
6298
59
        (void)posix_spawnattr_destroy(attrp);
6299
59
    }
6300
89
    if (envlist) {
  Branch (6300:9): [True: 89, False: 0]
6301
89
        free_string_array(envlist, envc);
6302
89
    }
6303
89
    if (argvlist) {
  Branch (6303:9): [True: 89, False: 0]
6304
89
        free_string_array(argvlist, argc);
6305
89
    }
6306
89
    Py_XDECREF(temp_buffer);
Line
Count
Source
613
89
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
89
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
89
#  define _Py_CAST(type, expr) ((type)(expr))
6307
89
    return result;
6308
57
}
6309
6310
6311
/*[clinic input]
6312
6313
os.posix_spawn
6314
    path: path_t
6315
        Path of executable file.
6316
    argv: object
6317
        Tuple or list of strings.
6318
    env: object
6319
        Dictionary of strings mapping to strings.
6320
    /
6321
    *
6322
    file_actions: object(c_default='NULL') = ()
6323
        A sequence of file action tuples.
6324
    setpgroup: object = NULL
6325
        The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6326
    resetids: bool(accept={int}) = False
6327
        If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
6328
    setsid: bool(accept={int}) = False
6329
        If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
6330
    setsigmask: object(c_default='NULL') = ()
6331
        The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6332
    setsigdef: object(c_default='NULL') = ()
6333
        The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6334
    scheduler: object = NULL
6335
        A tuple with the scheduler policy (optional) and parameters.
6336
6337
Execute the program specified by path in a new process.
6338
[clinic start generated code]*/
6339
6340
static PyObject *
6341
os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
6342
                    PyObject *env, PyObject *file_actions,
6343
                    PyObject *setpgroup, int resetids, int setsid,
6344
                    PyObject *setsigmask, PyObject *setsigdef,
6345
                    PyObject *scheduler)
6346
/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
6347
57
{
6348
57
    return py_posix_spawn(0, module, path, argv, env, file_actions,
6349
57
                          setpgroup, resetids, setsid, setsigmask, setsigdef,
6350
57
                          scheduler);
6351
57
}
6352
 #endif /* HAVE_POSIX_SPAWN */
6353
6354
6355
6356
#ifdef HAVE_POSIX_SPAWNP
6357
/*[clinic input]
6358
6359
os.posix_spawnp
6360
    path: path_t
6361
        Path of executable file.
6362
    argv: object
6363
        Tuple or list of strings.
6364
    env: object
6365
        Dictionary of strings mapping to strings.
6366
    /
6367
    *
6368
    file_actions: object(c_default='NULL') = ()
6369
        A sequence of file action tuples.
6370
    setpgroup: object = NULL
6371
        The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6372
    resetids: bool(accept={int}) = False
6373
        If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
6374
    setsid: bool(accept={int}) = False
6375
        If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
6376
    setsigmask: object(c_default='NULL') = ()
6377
        The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6378
    setsigdef: object(c_default='NULL') = ()
6379
        The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6380
    scheduler: object = NULL
6381
        A tuple with the scheduler policy (optional) and parameters.
6382
6383
Execute the program specified by path in a new process.
6384
[clinic start generated code]*/
6385
6386
static PyObject *
6387
os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
6388
                     PyObject *env, PyObject *file_actions,
6389
                     PyObject *setpgroup, int resetids, int setsid,
6390
                     PyObject *setsigmask, PyObject *setsigdef,
6391
                     PyObject *scheduler)
6392
/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
6393
32
{
6394
32
    return py_posix_spawn(1, module, path, argv, env, file_actions,
6395
32
                          setpgroup, resetids, setsid, setsigmask, setsigdef,
6396
32
                          scheduler);
6397
32
}
6398
#endif /* HAVE_POSIX_SPAWNP */
6399
6400
#ifdef HAVE_RTPSPAWN
6401
static intptr_t
6402
_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
6403
               const char  *envp[])
6404
{
6405
     RTP_ID rtpid;
6406
     int status;
6407
     pid_t res;
6408
     int async_err = 0;
6409
6410
     /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
6411
        uStackSize=0 cannot be used, the default stack size is too small for
6412
        Python. */
6413
     if (envp) {
6414
         rtpid = rtpSpawn(rtpFileName, argv, envp,
6415
                          100, 0x1000000, 0, VX_FP_TASK);
6416
     }
6417
     else {
6418
         rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
6419
                          100, 0x1000000, 0, VX_FP_TASK);
6420
     }
6421
     if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
6422
         do {
6423
             res = waitpid((pid_t)rtpid, &status, 0);
6424
         } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6425
6426
         if (res < 0)
6427
             return RTP_ID_ERROR;
6428
         return ((intptr_t)status);
6429
     }
6430
     return ((intptr_t)rtpid);
6431
}
6432
#endif
6433
6434
#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
6435
/*[clinic input]
6436
os.spawnv
6437
6438
    mode: int
6439
        Mode of process creation.
6440
    path: path_t
6441
        Path of executable file.
6442
    argv: object
6443
        Tuple or list of strings.
6444
    /
6445
6446
Execute the program specified by path in a new process.
6447
[clinic start generated code]*/
6448
6449
static PyObject *
6450
os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
6451
/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
6452
{
6453
    EXECV_CHAR **argvlist;
6454
    int i;
6455
    Py_ssize_t argc;
6456
    intptr_t spawnval;
6457
    PyObject *(*getitem)(PyObject *, Py_ssize_t);
6458
6459
    /* spawnv has three arguments: (mode, path, argv), where
6460
       argv is a list or tuple of strings. */
6461
6462
    if (PyList_Check(argv)) {
6463
        argc = PyList_Size(argv);
6464
        getitem = PyList_GetItem;
6465
    }
6466
    else if (PyTuple_Check(argv)) {
6467
        argc = PyTuple_Size(argv);
6468
        getitem = PyTuple_GetItem;
6469
    }
6470
    else {
6471
        PyErr_SetString(PyExc_TypeError,
6472
                        "spawnv() arg 2 must be a tuple or list");
6473
        return NULL;
6474
    }
6475
    if (argc == 0) {
6476
        PyErr_SetString(PyExc_ValueError,
6477
            "spawnv() arg 2 cannot be empty");
6478
        return NULL;
6479
    }
6480
6481
    argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
6482
    if (argvlist == NULL) {
6483
        return PyErr_NoMemory();
6484
    }
6485
    for (i = 0; i < argc; i++) {
6486
        if (!fsconvert_strdup((*getitem)(argv, i),
6487
                              &argvlist[i])) {
6488
            free_string_array(argvlist, i);
6489
            PyErr_SetString(
6490
                PyExc_TypeError,
6491
                "spawnv() arg 2 must contain only strings");
6492
            return NULL;
6493
        }
6494
        if (i == 0 && !argvlist[0][0]) {
6495
            free_string_array(argvlist, i + 1);
6496
            PyErr_SetString(
6497
                PyExc_ValueError,
6498
                "spawnv() arg 2 first element cannot be empty");
6499
            return NULL;
6500
        }
6501
    }
6502
    argvlist[argc] = NULL;
6503
6504
#if !defined(HAVE_RTPSPAWN)
6505
    if (mode == _OLD_P_OVERLAY)
6506
        mode = _P_OVERLAY;
6507
#endif
6508
6509
    if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
6510
                    Py_None) < 0) {
6511
        free_string_array(argvlist, argc);
6512
        return NULL;
6513
    }
6514
6515
    Py_BEGIN_ALLOW_THREADS
6516
    _Py_BEGIN_SUPPRESS_IPH
6517
#ifdef HAVE_WSPAWNV
6518
    spawnval = _wspawnv(mode, path->wide, argvlist);
6519
#elif defined(HAVE_RTPSPAWN)
6520
    spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
6521
#else
6522
    spawnval = _spawnv(mode, path->narrow, argvlist);
6523
#endif
6524
    _Py_END_SUPPRESS_IPH
6525
    Py_END_ALLOW_THREADS
6526
6527
    free_string_array(argvlist, argc);
6528
6529
    if (spawnval == -1)
6530
        return posix_error();
6531
    else
6532
        return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
6533
}
6534
6535
/*[clinic input]
6536
os.spawnve
6537
6538
    mode: int
6539
        Mode of process creation.
6540
    path: path_t
6541
        Path of executable file.
6542
    argv: object
6543
        Tuple or list of strings.
6544
    env: object
6545
        Dictionary of strings mapping to strings.
6546
    /
6547
6548
Execute the program specified by path in a new process.
6549
[clinic start generated code]*/
6550
6551
static PyObject *
6552
os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
6553
                PyObject *env)
6554
/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
6555
{
6556
    EXECV_CHAR **argvlist;
6557
    EXECV_CHAR **envlist;
6558
    PyObject *res = NULL;
6559
    Py_ssize_t argc, i, envc;
6560
    intptr_t spawnval;
6561
    PyObject *(*getitem)(PyObject *, Py_ssize_t);
6562
    Py_ssize_t lastarg = 0;
6563
6564
    /* spawnve has four arguments: (mode, path, argv, env), where
6565
       argv is a list or tuple of strings and env is a dictionary
6566
       like posix.environ. */
6567
6568
    if (PyList_Check(argv)) {
6569
        argc = PyList_Size(argv);
6570
        getitem = PyList_GetItem;
6571
    }
6572
    else if (PyTuple_Check(argv)) {
6573
        argc = PyTuple_Size(argv);
6574
        getitem = PyTuple_GetItem;
6575
    }
6576
    else {
6577
        PyErr_SetString(PyExc_TypeError,
6578
                        "spawnve() arg 2 must be a tuple or list");
6579
        goto fail_0;
6580
    }
6581
    if (argc == 0) {
6582
        PyErr_SetString(PyExc_ValueError,
6583
            "spawnve() arg 2 cannot be empty");
6584
        goto fail_0;
6585
    }
6586
    if (!PyMapping_Check(env)) {
6587
        PyErr_SetString(PyExc_TypeError,
6588
                        "spawnve() arg 3 must be a mapping object");
6589
        goto fail_0;
6590
    }
6591
6592
    argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
6593
    if (argvlist == NULL) {
6594
        PyErr_NoMemory();
6595
        goto fail_0;
6596
    }
6597
    for (i = 0; i < argc; i++) {
6598
        if (!fsconvert_strdup((*getitem)(argv, i),
6599
                              &argvlist[i]))
6600
        {
6601
            lastarg = i;
6602
            goto fail_1;
6603
        }
6604
        if (i == 0 && !argvlist[0][0]) {
6605
            lastarg = i + 1;
6606
            PyErr_SetString(
6607
                PyExc_ValueError,
6608
                "spawnv() arg 2 first element cannot be empty");
6609
            goto fail_1;
6610
        }
6611
    }
6612
    lastarg = argc;
6613
    argvlist[argc] = NULL;
6614
6615
    envlist = parse_envlist(env, &envc);
6616
    if (envlist == NULL)
6617
        goto fail_1;
6618
6619
#if !defined(HAVE_RTPSPAWN)
6620
    if (mode == _OLD_P_OVERLAY)
6621
        mode = _P_OVERLAY;
6622
#endif
6623
6624
    if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
6625
        goto fail_2;
6626
    }
6627
6628
    Py_BEGIN_ALLOW_THREADS
6629
    _Py_BEGIN_SUPPRESS_IPH
6630
#ifdef HAVE_WSPAWNV
6631
    spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
6632
#elif defined(HAVE_RTPSPAWN)
6633
    spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6634
                           (const char **)envlist);
6635
#else
6636
    spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6637
#endif
6638
    _Py_END_SUPPRESS_IPH
6639
    Py_END_ALLOW_THREADS
6640
6641
    if (spawnval == -1)
6642
        (void) posix_error();
6643
    else
6644
        res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
6645
6646
  fail_2:
6647
    while (--envc >= 0) {
6648
        PyMem_Free(envlist[envc]);
6649
    }
6650
    PyMem_Free(envlist);
6651
  fail_1:
6652
    free_string_array(argvlist, lastarg);
6653
  fail_0:
6654
    return res;
6655
}
6656
6657
#endif /* HAVE_SPAWNV */
6658
6659
#ifdef HAVE_FORK
6660
6661
/* Helper function to validate arguments.
6662
   Returns 0 on success.  non-zero on failure with a TypeError raised.
6663
   If obj is non-NULL it must be callable.  */
6664
static int
6665
check_null_or_callable(PyObject *obj, const char* obj_name)
6666
42
{
6667
42
    if (obj && !PyCallable_Check(obj)) {
  Branch (6667:9): [True: 22, False: 20]
  Branch (6667:16): [True: 8, False: 14]
6668
8
        PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
6669
8
                     obj_name, _PyType_Name(Py_TYPE(obj)));
Line
Count
Source
138
8
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
8
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8
#  define _Py_CAST(type, expr) ((type)(expr))
6670
8
        return -1;
6671
8
    }
6672
34
    return 0;
6673
42
}
6674
6675
/*[clinic input]
6676
os.register_at_fork
6677
6678
    *
6679
    before: object=NULL
6680
        A callable to be called in the parent before the fork() syscall.
6681
    after_in_child: object=NULL
6682
        A callable to be called in the child after fork().
6683
    after_in_parent: object=NULL
6684
        A callable to be called in the parent after fork().
6685
6686
Register callables to be called when forking a new process.
6687
6688
'before' callbacks are called in reverse order.
6689
'after_in_child' and 'after_in_parent' callbacks are called in order.
6690
6691
[clinic start generated code]*/
6692
6693
static PyObject *
6694
os_register_at_fork_impl(PyObject *module, PyObject *before,
6695
                         PyObject *after_in_child, PyObject *after_in_parent)
6696
/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
6697
17
{
6698
17
    PyInterpreterState *interp;
6699
6700
17
    if (!before && !after_in_child && !after_in_parent) {
  Branch (6700:9): [True: 11, False: 6]
  Branch (6700:20): [True: 2, False: 9]
  Branch (6700:39): [True: 0, False: 2]
6701
0
        PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6702
0
        return NULL;
6703
0
    }
6704
17
    if (check_null_or_callable(before, "before") ||
  Branch (6704:9): [True: 3, False: 14]
6705
17
        check_null_or_callable(after_in_child, "after_in_child") ||
  Branch (6705:9): [True: 3, False: 11]
6706
17
        check_null_or_callable(after_in_parent, "after_in_parent")) {
  Branch (6706:9): [True: 2, False: 9]
6707
8
        return NULL;
6708
8
    }
6709
9
    interp = _PyInterpreterState_GET();
6710
6711
9
    if (register_at_forker(&interp->before_forkers, before)) {
  Branch (6711:9): [True: 0, False: 9]
6712
0
        return NULL;
6713
0
    }
6714
9
    if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
  Branch (6714:9): [True: 0, False: 9]
6715
0
        return NULL;
6716
0
    }
6717
9
    if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
  Branch (6717:9): [True: 0, False: 9]
6718
0
        return NULL;
6719
0
    }
6720
9
    Py_RETURN_NONE;
Line
Count
Source
661
9
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
9
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
9
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
9
#  define _Py_CAST(type, expr) ((type)(expr))
6721
9
}
6722
#endif /* HAVE_FORK */
6723
6724
6725
#ifdef HAVE_FORK1
6726
/*[clinic input]
6727
os.fork1
6728
6729
Fork a child process with a single multiplexed (i.e., not bound) thread.
6730
6731
Return 0 to child process and PID of child to parent process.
6732
[clinic start generated code]*/
6733
6734
static PyObject *
6735
os_fork1_impl(PyObject *module)
6736
/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
6737
{
6738
    pid_t pid;
6739
6740
    if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) {
6741
        PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6742
        return NULL;
6743
    }
6744
    PyOS_BeforeFork();
6745
    pid = fork1();
6746
    if (pid == 0) {
6747
        /* child: this clobbers and resets the import lock. */
6748
        PyOS_AfterFork_Child();
6749
    } else {
6750
        /* parent: release the import lock. */
6751
        PyOS_AfterFork_Parent();
6752
    }
6753
    if (pid == -1)
6754
        return posix_error();
6755
    return PyLong_FromPid(pid);
6756
}
6757
#endif /* HAVE_FORK1 */
6758
6759
6760
#ifdef HAVE_FORK
6761
/*[clinic input]
6762
os.fork
6763
6764
Fork a child process.
6765
6766
Return 0 to child process and PID of child to parent process.
6767
[clinic start generated code]*/
6768
6769
static PyObject *
6770
os_fork_impl(PyObject *module)
6771
/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
6772
895
{
6773
895
    pid_t pid;
6774
895
    PyInterpreterState *interp = _PyInterpreterState_GET();
6775
895
    if (interp->config._isolated_interpreter) {
  Branch (6775:9): [True: 2, False: 893]
6776
2
        PyErr_SetString(PyExc_RuntimeError,
6777
2
                        "fork not supported for isolated subinterpreters");
6778
2
        return NULL;
6779
2
    }
6780
893
    if (PySys_Audit("os.fork", NULL) < 0) {
  Branch (6780:9): [True: 0, False: 893]
6781
0
        return NULL;
6782
0
    }
6783
893
    PyOS_BeforeFork();
6784
893
    pid = fork();
6785
893
    if (pid == 0) {
  Branch (6785:9): [True: 0, False: 893]
6786
        /* child: this clobbers and resets the import lock. */
6787
0
        PyOS_AfterFork_Child();
6788
893
    } else {
6789
        /* parent: release the import lock. */
6790
893
        PyOS_AfterFork_Parent();
6791
893
    }
6792
893
    if (pid == -1)
  Branch (6792:9): [True: 0, False: 893]
6793
0
        return posix_error();
6794
893
    return PyLong_FromPid(pid);
Line
Count
Source
36
893
#define PyLong_FromPid PyLong_FromLong
6795
893
}
6796
#endif /* HAVE_FORK */
6797
6798
6799
#ifdef HAVE_SCHED_H
6800
#ifdef HAVE_SCHED_GET_PRIORITY_MAX
6801
/*[clinic input]
6802
os.sched_get_priority_max
6803
6804
    policy: int
6805
6806
Get the maximum scheduling priority for policy.
6807
[clinic start generated code]*/
6808
6809
static PyObject *
6810
os_sched_get_priority_max_impl(PyObject *module, int policy)
6811
/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
6812
2
{
6813
2
    int max;
6814
6815
2
    max = sched_get_priority_max(policy);
6816
2
    if (max < 0)
  Branch (6816:9): [True: 1, False: 1]
6817
1
        return posix_error();
6818
1
    return PyLong_FromLong(max);
6819
2
}
6820
6821
6822
/*[clinic input]
6823
os.sched_get_priority_min
6824
6825
    policy: int
6826
6827
Get the minimum scheduling priority for policy.
6828
[clinic start generated code]*/
6829
6830
static PyObject *
6831
os_sched_get_priority_min_impl(PyObject *module, int policy)
6832
/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
6833
6
{
6834
6
    int min = sched_get_priority_min(policy);
6835
6
    if (min < 0)
  Branch (6835:9): [True: 1, False: 5]
6836
1
        return posix_error();
6837
5
    return PyLong_FromLong(min);
6838
6
}
6839
#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6840
6841
6842
#ifdef HAVE_SCHED_SETSCHEDULER
6843
/*[clinic input]
6844
os.sched_getscheduler
6845
    pid: pid_t
6846
    /
6847
6848
Get the scheduling policy for the process identified by pid.
6849
6850
Passing 0 for pid returns the scheduling policy for the calling process.
6851
[clinic start generated code]*/
6852
6853
static PyObject *
6854
os_sched_getscheduler_impl(PyObject *module, pid_t pid)
6855
/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
6856
8
{
6857
8
    int policy;
6858
6859
8
    policy = sched_getscheduler(pid);
6860
8
    if (policy < 0)
  Branch (6860:9): [True: 1, False: 7]
6861
1
        return posix_error();
6862
7
    return PyLong_FromLong(policy);
6863
8
}
6864
#endif /* HAVE_SCHED_SETSCHEDULER */
6865
6866
6867
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
6868
/*[clinic input]
6869
class os.sched_param "PyObject *" "SchedParamType"
6870
6871
@classmethod
6872
os.sched_param.__new__
6873
6874
    sched_priority: object
6875
        A scheduling parameter.
6876
6877
Currently has only one field: sched_priority
6878
[clinic start generated code]*/
6879
6880
static PyObject *
6881
os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
6882
/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
6883
7
{
6884
7
    PyObject *res;
6885
6886
7
    res = PyStructSequence_New(type);
6887
7
    if (!res)
  Branch (6887:9): [True: 0, False: 7]
6888
0
        return NULL;
6889
7
    Py_INCREF(sched_priority);
Line
Count
Source
512
7
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
7
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7
#  define _Py_CAST(type, expr) ((type)(expr))
6890
7
    PyStructSequence_SET_ITEM(res, 0, sched_priority);
Line
Count
Source
38
7
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
7
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
7
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
7
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7
#  define _Py_CAST(type, expr) ((type)(expr))
6891
7
    return res;
6892
7
}
6893
6894
PyDoc_VAR(os_sched_param__doc__);
6895
6896
static PyStructSequence_Field sched_param_fields[] = {
6897
    {"sched_priority", "the scheduling priority"},
6898
    {0}
6899
};
6900
6901
static PyStructSequence_Desc sched_param_desc = {
6902
    "sched_param", /* name */
6903
    os_sched_param__doc__, /* doc */
6904
    sched_param_fields,
6905
    1
6906
};
6907
6908
static int
6909
convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
6910
13
{
6911
13
    long priority;
6912
6913
13
    if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Line
Count
Source
155
13
#  define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), (type))
Line
Count
Source
109
13
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
13
#  define _Py_CAST(type, expr) ((type)(expr))
  Branch (6913:9): [True: 2, False: 11]
6914
2
        PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6915
2
        return 0;
6916
2
    }
6917
11
    priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
Line
Count
Source
40
11
#define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM((op), (i))
Line
Count
Source
28
11
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)])
Line
Count
Source
18
11
    (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op)))
Line
Count
Source
71
11
#  define _Py_CAST(type, expr) ((type)(expr))
6918
11
    if (priority == -1 && PyErr_Occurred())
  Branch (6918:9): [True: 1, False: 10]
  Branch (6918:27): [True: 1, False: 0]
6919
1
        return 0;
6920
10
    if (priority > INT_MAX || priority < INT_MIN) {
  Branch (6920:9): [True: 1, False: 9]
  Branch (6920:31): [True: 1, False: 8]
6921
2
        PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6922
2
        return 0;
6923
2
    }
6924
8
    res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
Line
Count
Source
348
8
#  define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) _Py_STATIC_CAST(NARROW, (VALUE))
Line
Count
Source
70
8
#  define _Py_STATIC_CAST(type, expr) ((type)(expr))
6925
8
    return 1;
6926
10
}
6927
#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
6928
6929
6930
#ifdef HAVE_SCHED_SETSCHEDULER
6931
/*[clinic input]
6932
os.sched_setscheduler
6933
6934
    pid: pid_t
6935
    policy: int
6936
    param as param_obj: object
6937
    /
6938
6939
Set the scheduling policy for the process identified by pid.
6940
6941
If pid is 0, the calling process is changed.
6942
param is an instance of sched_param.
6943
[clinic start generated code]*/
6944
6945
static PyObject *
6946
os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
6947
                           PyObject *param_obj)
6948
/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
6949
3
{
6950
3
    struct sched_param param;
6951
3
    if (!convert_sched_param(module, param_obj, &param)) {
  Branch (6951:9): [True: 1, False: 2]
6952
1
        return NULL;
6953
1
    }
6954
6955
    /*
6956
    ** sched_setscheduler() returns 0 in Linux, but the previous
6957
    ** scheduling policy under Solaris/Illumos, and others.
6958
    ** On error, -1 is returned in all Operating Systems.
6959
    */
6960
2
    if (sched_setscheduler(pid, policy, &param) == -1)
  Branch (6960:9): [True: 1, False: 1]
6961
1
        return posix_error();
6962
2
    Py_RETURN_NONE;
Line
Count
Source
661
1
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
6963
2
}
6964
#endif  /* HAVE_SCHED_SETSCHEDULER*/
6965
6966
6967
#ifdef HAVE_SCHED_SETPARAM
6968
/*[clinic input]
6969
os.sched_getparam
6970
    pid: pid_t
6971
    /
6972
6973
Returns scheduling parameters for the process identified by pid.
6974
6975
If pid is 0, returns parameters for the calling process.
6976
Return value is an instance of sched_param.
6977
[clinic start generated code]*/
6978
6979
static PyObject *
6980
os_sched_getparam_impl(PyObject *module, pid_t pid)
6981
/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
6982
2
{
6983
2
    struct sched_param param;
6984
2
    PyObject *result;
6985
2
    PyObject *priority;
6986
6987
2
    if (sched_getparam(pid, &param))
  Branch (6987:9): [True: 1, False: 1]
6988
1
        return posix_error();
6989
1
    PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
6990
1
    result = PyStructSequence_New((PyTypeObject *)SchedParamType);
6991
1
    if (!result)
  Branch (6991:9): [True: 0, False: 1]
6992
0
        return NULL;
6993
1
    priority = PyLong_FromLong(param.sched_priority);
6994
1
    if (!priority) {
  Branch (6994:9): [True: 0, False: 1]
6995
0
        Py_DECREF(result);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
6996
0
        return NULL;
6997
0
    }
6998
1
    PyStructSequence_SET_ITEM(result, 0, priority);
Line
Count
Source
38
1
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
1
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
6999
1
    return result;
7000
1
}
7001
7002
7003
/*[clinic input]
7004
os.sched_setparam
7005
    pid: pid_t
7006
    param as param_obj: object
7007
    /
7008
7009
Set scheduling parameters for the process identified by pid.
7010
7011
If pid is 0, sets parameters for the calling process.
7012
param should be an instance of sched_param.
7013
[clinic start generated code]*/
7014
7015
static PyObject *
7016
os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
7017
/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
7018
6
{
7019
6
    struct sched_param param;
7020
6
    if (!convert_sched_param(module, param_obj, &param)) {
  Branch (7020:9): [True: 4, False: 2]
7021
4
        return NULL;
7022
4
    }
7023
7024
2
    if (sched_setparam(pid, &param))
  Branch (7024:9): [True: 1, False: 1]
7025
1
        return posix_error();
7026
2
    Py_RETURN_NONE;
Line
Count
Source
661
1
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
7027
2
}
7028
#endif /* HAVE_SCHED_SETPARAM */
7029
7030
7031
#ifdef HAVE_SCHED_RR_GET_INTERVAL
7032
/*[clinic input]
7033
os.sched_rr_get_interval -> double
7034
    pid: pid_t
7035
    /
7036
7037
Return the round-robin quantum for the process identified by pid, in seconds.
7038
7039
Value returned is a float.
7040
[clinic start generated code]*/
7041
7042
static double
7043
os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
7044
/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
7045
1
{
7046
1
    struct timespec interval;
7047
1
    if (sched_rr_get_interval(pid, &interval)) {
  Branch (7047:9): [True: 0, False: 1]
7048
0
        posix_error();
7049
0
        return -1.0;
7050
0
    }
7051
#ifdef _Py_MEMORY_SANITIZER
7052
    __msan_unpoison(&interval, sizeof(interval));
7053
#endif
7054
1
    return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
7055
1
}
7056
#endif /* HAVE_SCHED_RR_GET_INTERVAL */
7057
7058
7059
/*[clinic input]
7060
os.sched_yield
7061
7062
Voluntarily relinquish the CPU.
7063
[clinic start generated code]*/
7064
7065
static PyObject *
7066
os_sched_yield_impl(PyObject *module)
7067
/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
7068
1
{
7069
1
    if (sched_yield())
  Branch (7069:9): [True: 0, False: 1]
7070
0
        return posix_error();
7071
1
    Py_RETURN_NONE;
Line
Count
Source
661
1
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
7072
1
}
7073
7074
#ifdef HAVE_SCHED_SETAFFINITY
7075
/* The minimum number of CPUs allocated in a cpu_set_t */
7076
static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
7077
7078
/*[clinic input]
7079
os.sched_setaffinity
7080
    pid: pid_t
7081
    mask : object
7082
    /
7083
7084
Set the CPU affinity of the process identified by pid to mask.
7085
7086
mask should be an iterable of integers identifying CPUs.
7087
[clinic start generated code]*/
7088
7089
static PyObject *
7090
os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
7091
/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
7092
6
{
7093
6
    int ncpus;
7094
6
    size_t setsize;
7095
6
    cpu_set_t *cpu_set = NULL;
7096
6
    PyObject *iterator = NULL, *item;
7097
7098
6
    iterator = PyObject_GetIter(mask);
7099
6
    if (iterator == NULL)
  Branch (7099:9): [True: 0, False: 6]
7100
0
        return NULL;
7101
7102
6
    ncpus = NCPUS_START;
7103
6
    setsize = CPU_ALLOC_SIZE(ncpus);
7104
6
    cpu_set = CPU_ALLOC(ncpus);
7105
6
    if (cpu_set == NULL) {
  Branch (7105:9): [True: 0, False: 6]
7106
0
        PyErr_NoMemory();
7107
0
        goto error;
7108
0
    }
7109
6
    CPU_ZERO_S(setsize, cpu_set);
7110
7111
37
    while ((item = PyIter_Next(iterator))) {
  Branch (7111:12): [True: 33, False: 4]
7112
33
        long cpu;
7113
33
        if (!PyLong_Check(item)) {
Line
Count
Source
13
33
        PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS)
Line
Count
Source
782
33
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (7113:13): [True: 0, False: 33]
7114
0
            PyErr_Format(PyExc_TypeError,
7115
0
                        "expected an iterator of ints, "
7116
0
                        "but iterator yielded %R",
7117
0
                        Py_TYPE(item));
Line
Count
Source
138
0
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
7118
0
            Py_DECREF(item);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
7119
0
            goto error;
7120
0
        }
7121
33
        cpu = PyLong_AsLong(item);
7122
33
        Py_DECREF(item);
Line
Count
Source
548
33
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
33
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
33
#  define _Py_CAST(type, expr) ((type)(expr))
7123
33
        if (cpu < 0) {
  Branch (7123:13): [True: 2, False: 31]
7124
2
            if (!PyErr_Occurred())
  Branch (7124:17): [True: 1, False: 1]
7125
1
                PyErr_SetString(PyExc_ValueError, "negative CPU number");
7126
2
            goto error;
7127
2
        }
7128
31
        if (cpu > INT_MAX - 1) {
  Branch (7128:13): [True: 0, False: 31]
7129
0
            PyErr_SetString(PyExc_OverflowError, "CPU number too large");
7130
0
            goto error;
7131
0
        }
7132
31
        if (cpu >= ncpus) {
  Branch (7132:13): [True: 0, False: 31]
7133
            /* Grow CPU mask to fit the CPU number */
7134
0
            int newncpus = ncpus;
7135
0
            cpu_set_t *newmask;
7136
0
            size_t newsetsize;
7137
0
            while (newncpus <= cpu) {
  Branch (7137:20): [True: 0, False: 0]
7138
0
                if (newncpus > INT_MAX / 2)
  Branch (7138:21): [True: 0, False: 0]
7139
0
                    newncpus = cpu + 1;
7140
0
                else
7141
0
                    newncpus = newncpus * 2;
7142
0
            }
7143
0
            newmask = CPU_ALLOC(newncpus);
7144
0
            if (newmask == NULL) {
  Branch (7144:17): [True: 0, False: 0]
7145
0
                PyErr_NoMemory();
7146
0
                goto error;
7147
0
            }
7148
0
            newsetsize = CPU_ALLOC_SIZE(newncpus);
7149
0
            CPU_ZERO_S(newsetsize, newmask);
7150
0
            memcpy(newmask, cpu_set, setsize);
7151
0
            CPU_FREE(cpu_set);
7152
0
            setsize = newsetsize;
7153
0
            cpu_set = newmask;
7154
0
            ncpus = newncpus;
7155
0
        }
7156
31
        CPU_SET_S(cpu, setsize, cpu_set);
7157
31
    }
7158
4
    if (PyErr_Occurred()) {
  Branch (7158:9): [True: 1, False: 3]
7159
1
        goto error;
7160
1
    }
7161
3
    Py_CLEAR(iterator);
Line
Count
Source
587
3
    do {                                        \
588
3
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
3
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
3
#  define _Py_CAST(type, expr) ((type)(expr))
589
3
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 3, False: 0]
590
3
            (op) = NULL;                        \
591
3
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
3
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
3
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
3
#  define _Py_CAST(type, expr) ((type)(expr))
592
3
        }                                       \
593
3
    } while (0)
  Branch (593:14): [Folded - Ignored]
7162
7163
3
    if (sched_setaffinity(pid, setsize, cpu_set)) {
  Branch (7163:9): [True: 2, False: 1]
7164
2
        posix_error();
7165
2
        goto error;
7166
2
    }
7167
1
    CPU_FREE(cpu_set);
7168
1
    Py_RETURN_NONE;
Line
Count
Source
661
1
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
7169
7170
5
error:
7171
5
    if (cpu_set)
  Branch (7171:9): [True: 5, False: 0]
7172
5
        CPU_FREE(cpu_set);
7173
5
    Py_XDECREF(iterator);
Line
Count
Source
613
5
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
5
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5
#  define _Py_CAST(type, expr) ((type)(expr))
7174
5
    return NULL;
7175
3
}
7176
7177
7178
/*[clinic input]
7179
os.sched_getaffinity
7180
    pid: pid_t
7181
    /
7182
7183
Return the affinity of the process identified by pid (or the current process if zero).
7184
7185
The affinity is returned as a set of CPU identifiers.
7186
[clinic start generated code]*/
7187
7188
static PyObject *
7189
os_sched_getaffinity_impl(PyObject *module, pid_t pid)
7190
/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
7191
4
{
7192
4
    int cpu, ncpus, count;
7193
4
    size_t setsize;
7194
4
    cpu_set_t *mask = NULL;
7195
4
    PyObject *res = NULL;
7196
7197
4
    ncpus = NCPUS_START;
7198
4
    while (1) {
  Branch (7198:12): [Folded - Ignored]
7199
4
        setsize = CPU_ALLOC_SIZE(ncpus);
7200
4
        mask = CPU_ALLOC(ncpus);
7201
4
        if (mask == NULL)
  Branch (7201:13): [True: 0, False: 4]
7202
0
            return PyErr_NoMemory();
7203
4
        if (sched_getaffinity(pid, setsize, mask) == 0)
  Branch (7203:13): [True: 3, False: 1]
7204
3
            break;
7205
1
        CPU_FREE(mask);
7206
1
        if (errno != EINVAL)
  Branch (7206:13): [True: 1, False: 0]
7207
1
            return posix_error();
7208
0
        if (ncpus > INT_MAX / 2) {
  Branch (7208:13): [True: 0, False: 0]
7209
0
            PyErr_SetString(PyExc_OverflowError, "could not allocate "
7210
0
                            "a large enough CPU set");
7211
0
            return NULL;
7212
0
        }
7213
0
        ncpus = ncpus * 2;
7214
0
    }
7215
7216
3
    res = PySet_New(NULL);
7217
3
    if (res == NULL)
  Branch (7217:9): [True: 0, False: 3]
7218
0
        goto error;
7219
51
    for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
  Branch (7219:55): [True: 48, False: 3]
7220
48
        if (CPU_ISSET_S(cpu, setsize, mask)) {
7221
47
            PyObject *cpu_num = PyLong_FromLong(cpu);
7222
47
            --count;
7223
47
            if (cpu_num == NULL)
  Branch (7223:17): [True: 0, False: 47]
7224
0
                goto error;
7225
47
            if (PySet_Add(res, cpu_num)) {
  Branch (7225:17): [True: 0, False: 47]
7226
0
                Py_DECREF(cpu_num);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
7227
0
                goto error;
7228
0
            }
7229
47
            Py_DECREF(cpu_num);
Line
Count
Source
548
47
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
47
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
47
#  define _Py_CAST(type, expr) ((type)(expr))
7230
47
        }
7231
48
    }
7232
3
    CPU_FREE(mask);
7233
3
    return res;
7234
7235
0
error:
7236
0
    if (mask)
  Branch (7236:9): [True: 0, False: 0]
7237
0
        CPU_FREE(mask);
7238
0
    Py_XDECREF(res);
Line
Count
Source
613
0
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
7239
0
    return NULL;
7240
3
}
7241
7242
#endif /* HAVE_SCHED_SETAFFINITY */
7243
7244
#endif /* HAVE_SCHED_H */
7245
7246
7247
/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
7248
#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
7249
#  define DEV_PTY_FILE "/dev/ptc"
7250
#  define HAVE_DEV_PTMX
7251
#else
7252
#  define DEV_PTY_FILE "/dev/ptmx"
7253
#endif
7254
7255
#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_LOGIN_TTY) || defined(HAVE_DEV_PTMX)
7256
#ifdef HAVE_PTY_H
7257
#include <pty.h>
7258
#ifdef HAVE_UTMP_H
7259
#include <utmp.h>
7260
#endif /* HAVE_UTMP_H */
7261
#elif defined(HAVE_LIBUTIL_H)
7262
#include <libutil.h>
7263
#elif defined(HAVE_UTIL_H)
7264
#include <util.h>
7265
#endif /* HAVE_PTY_H */
7266
#ifdef HAVE_STROPTS_H
7267
#include <stropts.h>
7268
#endif
7269
#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_LOGIN_TTY) || defined(HAVE_DEV_PTMX) */
7270
7271
7272
#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
7273
/*[clinic input]
7274
os.openpty
7275
7276
Open a pseudo-terminal.
7277
7278
Return a tuple of (master_fd, slave_fd) containing open file descriptors
7279
for both the master and slave ends.
7280
[clinic start generated code]*/
7281
7282
static PyObject *
7283
os_openpty_impl(PyObject *module)
7284
/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
7285
18
{
7286
18
    int master_fd = -1, slave_fd = -1;
7287
#ifndef HAVE_OPENPTY
7288
    char * slave_name;
7289
#endif
7290
#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
7291
    PyOS_sighandler_t sig_saved;
7292
#if defined(__sun) && defined(__SVR4)
7293
    extern char *ptsname(int fildes);
7294
#endif
7295
#endif
7296
7297
18
#ifdef HAVE_OPENPTY
7298
18
    if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
  Branch (7298:9): [True: 0, False: 18]
7299
0
        goto posix_error;
7300
7301
18
    if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
  Branch (7301:9): [True: 0, False: 18]
7302
0
        goto error;
7303
18
    if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
  Branch (7303:9): [True: 0, False: 18]
7304
0
        goto error;
7305
7306
#elif defined(HAVE__GETPTY)
7307
    slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
7308
    if (slave_name == NULL)
7309
        goto posix_error;
7310
    if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7311
        goto error;
7312
7313
    slave_fd = _Py_open(slave_name, O_RDWR);
7314
    if (slave_fd < 0)
7315
        goto error;
7316
7317
#else
7318
    master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
7319
    if (master_fd < 0)
7320
        goto posix_error;
7321
7322
    sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
7323
7324
    /* change permission of slave */
7325
    if (grantpt(master_fd) < 0) {
7326
        PyOS_setsig(SIGCHLD, sig_saved);
7327
        goto posix_error;
7328
    }
7329
7330
    /* unlock slave */
7331
    if (unlockpt(master_fd) < 0) {
7332
        PyOS_setsig(SIGCHLD, sig_saved);
7333
        goto posix_error;
7334
    }
7335
7336
    PyOS_setsig(SIGCHLD, sig_saved);
7337
7338
    slave_name = ptsname(master_fd); /* get name of slave */
7339
    if (slave_name == NULL)
7340
        goto posix_error;
7341
7342
    slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
7343
    if (slave_fd == -1)
7344
        goto error;
7345
7346
    if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7347
        goto posix_error;
7348
7349
#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
7350
    ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
7351
    ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
7352
#ifndef __hpux
7353
    ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
7354
#endif /* __hpux */
7355
#endif /* HAVE_CYGWIN */
7356
#endif /* HAVE_OPENPTY */
7357
7358
18
    return Py_BuildValue("(ii)", master_fd, slave_fd);
Line
Count
Source
20
18
#define Py_BuildValue                   _Py_BuildValue_SizeT
7359
7360
0
posix_error:
7361
0
    posix_error();
7362
0
error:
7363
0
    if (master_fd != -1)
  Branch (7363:9): [True: 0, False: 0]
7364
0
        close(master_fd);
7365
0
    if (slave_fd != -1)
  Branch (7365:9): [True: 0, False: 0]
7366
0
        close(slave_fd);
7367
0
    return NULL;
7368
0
}
7369
#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
7370
7371
7372
#if defined(HAVE_SETSID) && defined(TIOCSCTTY)
7373
#define HAVE_FALLBACK_LOGIN_TTY 1
7374
#endif /* defined(HAVE_SETSID) && defined(TIOCSCTTY) */
7375
7376
#if defined(HAVE_LOGIN_TTY) || defined(HAVE_FALLBACK_LOGIN_TTY)
7377
/*[clinic input]
7378
os.login_tty
7379
7380
    fd: fildes
7381
    /
7382
7383
Prepare the tty of which fd is a file descriptor for a new login session.
7384
7385
Make the calling process a session leader; make the tty the
7386
controlling tty, the stdin, the stdout, and the stderr of the
7387
calling process; close fd.
7388
[clinic start generated code]*/
7389
7390
static PyObject *
7391
os_login_tty_impl(PyObject *module, int fd)
7392
/*[clinic end generated code: output=495a79911b4cc1bc input=5f298565099903a2]*/
7393
0
{
7394
0
#ifdef HAVE_LOGIN_TTY
7395
0
    if (login_tty(fd) == -1) {
  Branch (7395:9): [True: 0, False: 0]
7396
0
        return posix_error();
7397
0
    }
7398
#else /* defined(HAVE_FALLBACK_LOGIN_TTY) */
7399
    /* Establish a new session. */
7400
    if (setsid() == -1) {
7401
        return posix_error();
7402
    }
7403
7404
    /* The tty becomes the controlling terminal. */
7405
    if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1) {
7406
        return posix_error();
7407
    }
7408
7409
    /* The tty becomes stdin/stdout/stderr */
7410
    if (dup2(fd, 0) == -1 || dup2(fd, 1) == -1 || dup2(fd, 2) == -1) {
7411
        return posix_error();
7412
    }
7413
    if (fd > 2) {
7414
        close(fd);
7415
    }
7416
#endif /* HAVE_LOGIN_TTY */
7417
0
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
7418
0
}
7419
#endif /* defined(HAVE_LOGIN_TTY) || defined(HAVE_FALLBACK_LOGIN_TTY) */
7420
7421
7422
#ifdef HAVE_FORKPTY
7423
/*[clinic input]
7424
os.forkpty
7425
7426
Fork a new process with a new pseudo-terminal as controlling tty.
7427
7428
Returns a tuple of (pid, master_fd).
7429
Like fork(), return pid of 0 to the child process,
7430
and pid of child to the parent process.
7431
To both, return fd of newly opened pseudo-terminal.
7432
[clinic start generated code]*/
7433
7434
static PyObject *
7435
os_forkpty_impl(PyObject *module)
7436
/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
7437
6
{
7438
6
    int master_fd = -1;
7439
6
    pid_t pid;
7440
7441
6
    if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) {
  Branch (7441:9): [True: 0, False: 6]
7442
0
        PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
7443
0
        return NULL;
7444
0
    }
7445
6
    if (PySys_Audit("os.forkpty", NULL) < 0) {
  Branch (7445:9): [True: 0, False: 6]
7446
0
        return NULL;
7447
0
    }
7448
6
    PyOS_BeforeFork();
7449
6
    pid = forkpty(&master_fd, NULL, NULL, NULL);
7450
6
    if (pid == 0) {
  Branch (7450:9): [True: 0, False: 6]
7451
        /* child: this clobbers and resets the import lock. */
7452
0
        PyOS_AfterFork_Child();
7453
6
    } else {
7454
        /* parent: release the import lock. */
7455
6
        PyOS_AfterFork_Parent();
7456
6
    }
7457
6
    if (pid == -1) {
  Branch (7457:9): [True: 0, False: 6]
7458
0
        return posix_error();
7459
0
    }
7460
6
    return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Line
Count
Source
20
6
#define Py_BuildValue                   _Py_BuildValue_SizeT
    return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Line
Count
Source
36
6
#define PyLong_FromPid PyLong_FromLong
7461
6
}
7462
#endif /* HAVE_FORKPTY */
7463
7464
7465
#ifdef HAVE_GETEGID
7466
/*[clinic input]
7467
os.getegid
7468
7469
Return the current process's effective group id.
7470
[clinic start generated code]*/
7471
7472
static PyObject *
7473
os_getegid_impl(PyObject *module)
7474
/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
7475
265
{
7476
265
    return _PyLong_FromGid(getegid());
7477
265
}
7478
#endif /* HAVE_GETEGID */
7479
7480
7481
#ifdef HAVE_GETEUID
7482
/*[clinic input]
7483
os.geteuid
7484
7485
Return the current process's effective user id.
7486
[clinic start generated code]*/
7487
7488
static PyObject *
7489
os_geteuid_impl(PyObject *module)
7490
/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
7491
483
{
7492
483
    return _PyLong_FromUid(geteuid());
7493
483
}
7494
#endif /* HAVE_GETEUID */
7495
7496
7497
#ifdef HAVE_GETGID
7498
/*[clinic input]
7499
os.getgid
7500
7501
Return the current process's group id.
7502
[clinic start generated code]*/
7503
7504
static PyObject *
7505
os_getgid_impl(PyObject *module)
7506
/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
7507
268
{
7508
268
    return _PyLong_FromGid(getgid());
7509
268
}
7510
#endif /* HAVE_GETGID */
7511
7512
7513
#ifdef HAVE_GETPID
7514
/*[clinic input]
7515
os.getpid
7516
7517
Return the current process id.
7518
[clinic start generated code]*/
7519
7520
static PyObject *
7521
os_getpid_impl(PyObject *module)
7522
/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
7523
5.14M
{
7524
5.14M
    return PyLong_FromPid(getpid());
Line
Count
Source
36
5.14M
#define PyLong_FromPid PyLong_FromLong
7525
5.14M
}
7526
#endif /* HAVE_GETPID */
7527
7528
#ifdef NGROUPS_MAX
7529
1
#define MAX_GROUPS NGROUPS_MAX
7530
#else
7531
    /* defined to be 16 on Solaris7, so this should be a small number */
7532
#define MAX_GROUPS 64
7533
#endif
7534
7535
#ifdef HAVE_GETGROUPLIST
7536
7537
#ifdef __APPLE__
7538
/*[clinic input]
7539
os.getgrouplist
7540
7541
    user: str
7542
        username to lookup
7543
    group as basegid: int
7544
        base group id of the user
7545
    /
7546
7547
Returns a list of groups to which a user belongs.
7548
[clinic start generated code]*/
7549
7550
static PyObject *
7551
os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
7552
/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
7553
#else
7554
/*[clinic input]
7555
os.getgrouplist
7556
7557
    user: str
7558
        username to lookup
7559
    group as basegid: gid_t
7560
        base group id of the user
7561
    /
7562
7563
Returns a list of groups to which a user belongs.
7564
[clinic start generated code]*/
7565
7566
static PyObject *
7567
os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
7568
/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
7569
#endif
7570
1
{
7571
1
    int i, ngroups;
7572
1
    PyObject *list;
7573
#ifdef __APPLE__
7574
    int *groups;
7575
#else
7576
1
    gid_t *groups;
7577
1
#endif
7578
7579
    /*
7580
     * NGROUPS_MAX is defined by POSIX.1 as the maximum
7581
     * number of supplimental groups a users can belong to.
7582
     * We have to increment it by one because
7583
     * getgrouplist() returns both the supplemental groups
7584
     * and the primary group, i.e. all of the groups the
7585
     * user belongs to.
7586
     */
7587
1
    ngroups = 1 + MAX_GROUPS;
Line
Count
Source
7529
1
#define MAX_GROUPS NGROUPS_MAX
7588
7589
1
    while (1) {
  Branch (7589:12): [Folded - Ignored]
7590
#ifdef __APPLE__
7591
        groups = PyMem_New(int, ngroups);
7592
#else
7593
1
        groups = PyMem_New(gid_t, ngroups);
Line
Count
Source
68
1
  ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL :      \
Line
Count
Source
180
1
#   define PY_SSIZE_T_MAX SSIZE_MAX
  Branch (68:5): [True: 0, False: 1]
69
1
        ( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
7594
1
#endif
7595
1
        if (groups == NULL) {
  Branch (7595:13): [True: 0, False: 1]
7596
0
            return PyErr_NoMemory();
7597
0
        }
7598
7599
1
        int old_ngroups = ngroups;
7600
1
        if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
  Branch (7600:13): [True: 1, False: 0]
7601
            /* Success */
7602
1
            break;
7603
1
        }
7604
7605
        /* getgrouplist() fails if the group list is too small */
7606
0
        PyMem_Free(groups);
7607
7608
0
        if (ngroups > old_ngroups) {
  Branch (7608:13): [True: 0, False: 0]
7609
            /* If the group list is too small, the glibc implementation of
7610
               getgrouplist() sets ngroups to the total number of groups and
7611
               returns -1. */
7612
0
        }
7613
0
        else {
7614
            /* Double the group list size */
7615
0
            if (ngroups > INT_MAX / 2) {
  Branch (7615:17): [True: 0, False: 0]
7616
0
                return PyErr_NoMemory();
7617
0
            }
7618
0
            ngroups *= 2;
7619
0
        }
7620
7621
        /* Retry getgrouplist() with a larger group list */
7622
0
    }
7623
7624
#ifdef _Py_MEMORY_SANITIZER
7625
    /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7626
    __msan_unpoison(&ngroups, sizeof(ngroups));
7627
    __msan_unpoison(groups, ngroups*sizeof(*groups));
7628
#endif
7629
7630
1
    list = PyList_New(ngroups);
7631
1
    if (list == NULL) {
  Branch (7631:9): [True: 0, False: 1]
7632
0
        PyMem_Free(groups);
7633
0
        return NULL;
7634
0
    }
7635
7636
7
    for (i = 0; i < ngroups; i++) {
  Branch (7636:17): [True: 6, False: 1]
7637
#ifdef __APPLE__
7638
        PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
7639
#else
7640
6
        PyObject *o = _PyLong_FromGid(groups[i]);
7641
6
#endif
7642
6
        if (o == NULL) {
  Branch (7642:13): [True: 0, False: 6]
7643
0
            Py_DECREF(list);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
7644
0
            PyMem_Free(groups);
7645
0
            return NULL;
7646
0
        }
7647
6
        PyList_SET_ITEM(list, i, o);
Line
Count
Source
47
6
    PyList_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
6
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
6
#  define _Py_CAST(type, expr) ((type)(expr))
    PyList_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
6
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
6
#  define _Py_CAST(type, expr) ((type)(expr))
7648
6
    }
7649
7650
1
    PyMem_Free(groups);
7651
7652
1
    return list;
7653
1
}
7654
#endif /* HAVE_GETGROUPLIST */
7655
7656
7657
#ifdef HAVE_GETGROUPS
7658
/*[clinic input]
7659
os.getgroups
7660
7661
Return list of supplemental group IDs for the process.
7662
[clinic start generated code]*/
7663
7664
static PyObject *
7665
os_getgroups_impl(PyObject *module)
7666
/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
7667
6
{
7668
    // Call getgroups with length 0 to get the actual number of groups
7669
6
    int n = getgroups(0, NULL);
7670
6
    if (n < 0) {
  Branch (7670:9): [True: 0, False: 6]
7671
0
        return posix_error();
7672
0
    }
7673
7674
6
    if (n == 0) {
  Branch (7674:9): [True: 0, False: 6]
7675
0
        return PyList_New(0);
7676
0
    }
7677
7678
6
    gid_t *grouplist = PyMem_New(gid_t, n);
Line
Count
Source
68
6
  ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL :      \
Line
Count
Source
180
6
#   define PY_SSIZE_T_MAX SSIZE_MAX
  Branch (68:5): [True: 0, False: 6]
69
6
        ( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
7679
6
    if (grouplist == NULL) {
  Branch (7679:9): [True: 0, False: 6]
7680
0
        return PyErr_NoMemory();
7681
0
    }
7682
7683
6
    n = getgroups(n, grouplist);
7684
6
    if (n == -1) {
  Branch (7684:9): [True: 0, False: 6]
7685
0
        PyMem_Free(grouplist);
7686
0
        return posix_error();
7687
0
    }
7688
7689
6
    PyObject *result = PyList_New(n);
7690
6
    if (result == NULL) {
  Branch (7690:9): [True: 0, False: 6]
7691
0
        goto error;
7692
0
    }
7693
7694
42
    for (int i = 0; i < n; ++i) {
  Branch (7694:21): [True: 36, False: 6]
7695
36
        PyObject *group = _PyLong_FromGid(grouplist[i]);
7696
36
        if (group == NULL) {
  Branch (7696:13): [True: 0, False: 36]
7697
0
            goto error;
7698
0
        }
7699
36
        PyList_SET_ITEM(result, i, group);
Line
Count
Source
47
36
    PyList_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
36
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
36
#  define _Py_CAST(type, expr) ((type)(expr))
    PyList_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
36
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
36
#  define _Py_CAST(type, expr) ((type)(expr))
7700
36
    }
7701
6
    PyMem_Free(grouplist);
7702
7703
6
    return result;
7704
7705
0
error:
7706
0
    PyMem_Free(grouplist);
7707
0
    Py_XDECREF(result);
Line
Count
Source
613
0
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
7708
0
    return NULL;
7709
6
}
7710
#endif /* HAVE_GETGROUPS */
7711
7712
#ifdef HAVE_INITGROUPS
7713
#ifdef __APPLE__
7714
/*[clinic input]
7715
os.initgroups
7716
7717
    username as oname: FSConverter
7718
    gid: int
7719
    /
7720
7721
Initialize the group access list.
7722
7723
Call the system initgroups() to initialize the group access list with all of
7724
the groups of which the specified username is a member, plus the specified
7725
group id.
7726
[clinic start generated code]*/
7727
7728
static PyObject *
7729
os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7730
/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7731
#else
7732
/*[clinic input]
7733
os.initgroups
7734
7735
    username as oname: FSConverter
7736
    gid: gid_t
7737
    /
7738
7739
Initialize the group access list.
7740
7741
Call the system initgroups() to initialize the group access list with all of
7742
the groups of which the specified username is a member, plus the specified
7743
group id.
7744
[clinic start generated code]*/
7745
7746
static PyObject *
7747
os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7748
/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7749
#endif
7750
1
{
7751
1
    const char *username = PyBytes_AS_STRING(oname);
Line
Count
Source
39
1
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
7752
7753
1
    if (initgroups(username, gid) == -1)
  Branch (7753:9): [True: 1, False: 0]
7754
1
        return PyErr_SetFromErrno(PyExc_OSError);
7755
7756
1
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
7757
1
}
7758
#endif /* HAVE_INITGROUPS */
7759
7760
7761
#ifdef HAVE_GETPGID
7762
/*[clinic input]
7763
os.getpgid
7764
7765
    pid: pid_t
7766
7767
Call the system call getpgid(), and return the result.
7768
[clinic start generated code]*/
7769
7770
static PyObject *
7771
os_getpgid_impl(PyObject *module, pid_t pid)
7772
/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
7773
1
{
7774
1
    pid_t pgid = getpgid(pid);
7775
1
    if (pgid < 0)
  Branch (7775:9): [True: 0, False: 1]
7776
0
        return posix_error();
7777
1
    return PyLong_FromPid(pgid);
Line
Count
Source
36
1
#define PyLong_FromPid PyLong_FromLong
7778
1
}
7779
#endif /* HAVE_GETPGID */
7780
7781
7782
#ifdef HAVE_GETPGRP
7783
/*[clinic input]
7784
os.getpgrp
7785
7786
Return the current process group id.
7787
[clinic start generated code]*/
7788
7789
static PyObject *
7790
os_getpgrp_impl(PyObject *module)
7791
/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
7792
8
{
7793
#ifdef GETPGRP_HAVE_ARG
7794
    return PyLong_FromPid(getpgrp(0));
7795
#else /* GETPGRP_HAVE_ARG */
7796
8
    return PyLong_FromPid(getpgrp());
Line
Count
Source
36
8
#define PyLong_FromPid PyLong_FromLong
7797
8
#endif /* GETPGRP_HAVE_ARG */
7798
8
}
7799
#endif /* HAVE_GETPGRP */
7800
7801
7802
#ifdef HAVE_SETPGRP
7803
/*[clinic input]
7804
os.setpgrp
7805
7806
Make the current process the leader of its process group.
7807
[clinic start generated code]*/
7808
7809
static PyObject *
7810
os_setpgrp_impl(PyObject *module)
7811
/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
7812
0
{
7813
#ifdef SETPGRP_HAVE_ARG
7814
    if (setpgrp(0, 0) < 0)
7815
#else /* SETPGRP_HAVE_ARG */
7816
0
    if (setpgrp() < 0)
  Branch (7816:9): [True: 0, False: 0]
7817
0
#endif /* SETPGRP_HAVE_ARG */
7818
0
        return posix_error();
7819
0
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
7820
0
}
7821
#endif /* HAVE_SETPGRP */
7822
7823
#ifdef HAVE_GETPPID
7824
7825
#ifdef MS_WINDOWS
7826
#include <tlhelp32.h>
7827
7828
static PyObject*
7829
win32_getppid()
7830
{
7831
    HANDLE snapshot;
7832
    pid_t mypid;
7833
    PyObject* result = NULL;
7834
    BOOL have_record;
7835
    PROCESSENTRY32 pe;
7836
7837
    mypid = getpid(); /* This function never fails */
7838
7839
    snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7840
    if (snapshot == INVALID_HANDLE_VALUE)
7841
        return PyErr_SetFromWindowsErr(GetLastError());
7842
7843
    pe.dwSize = sizeof(pe);
7844
    have_record = Process32First(snapshot, &pe);
7845
    while (have_record) {
7846
        if (mypid == (pid_t)pe.th32ProcessID) {
7847
            /* We could cache the ulong value in a static variable. */
7848
            result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7849
            break;
7850
        }
7851
7852
        have_record = Process32Next(snapshot, &pe);
7853
    }
7854
7855
    /* If our loop exits and our pid was not found (result will be NULL)
7856
     * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7857
     * error anyway, so let's raise it. */
7858
    if (!result)
7859
        result = PyErr_SetFromWindowsErr(GetLastError());
7860
7861
    CloseHandle(snapshot);
7862
7863
    return result;
7864
}
7865
#endif /*MS_WINDOWS*/
7866
7867
7868
/*[clinic input]
7869
os.getppid
7870
7871
Return the parent's process id.
7872
7873
If the parent process has already exited, Windows machines will still
7874
return its id; others systems will return the id of the 'init' process (1).
7875
[clinic start generated code]*/
7876
7877
static PyObject *
7878
os_getppid_impl(PyObject *module)
7879
/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
7880
2
{
7881
#ifdef MS_WINDOWS
7882
    return win32_getppid();
7883
#else
7884
2
    return PyLong_FromPid(getppid());
Line
Count
Source
36
2
#define PyLong_FromPid PyLong_FromLong
7885
2
#endif
7886
2
}
7887
#endif /* HAVE_GETPPID */
7888
7889
7890
#ifdef HAVE_GETLOGIN
7891
/*[clinic input]
7892
os.getlogin
7893
7894
Return the actual login name.
7895
[clinic start generated code]*/
7896
7897
static PyObject *
7898
os_getlogin_impl(PyObject *module)
7899
/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
7900
0
{
7901
0
    PyObject *result = NULL;
7902
#ifdef MS_WINDOWS
7903
    wchar_t user_name[UNLEN + 1];
7904
    DWORD num_chars = Py_ARRAY_LENGTH(user_name);
7905
7906
    if (GetUserNameW(user_name, &num_chars)) {
7907
        /* num_chars is the number of unicode chars plus null terminator */
7908
        result = PyUnicode_FromWideChar(user_name, num_chars - 1);
7909
    }
7910
    else
7911
        result = PyErr_SetFromWindowsErr(GetLastError());
7912
#else
7913
0
    char *name;
7914
0
    int old_errno = errno;
7915
7916
0
    errno = 0;
7917
0
    name = getlogin();
7918
0
    if (name == NULL) {
  Branch (7918:9): [True: 0, False: 0]
7919
0
        if (errno)
7920
0
            posix_error();
7921
0
        else
7922
0
            PyErr_SetString(PyExc_OSError, "unable to determine login name");
7923
0
    }
7924
0
    else
7925
0
        result = PyUnicode_DecodeFSDefault(name);
7926
0
    errno = old_errno;
7927
0
#endif
7928
0
    return result;
7929
0
}
7930
#endif /* HAVE_GETLOGIN */
7931
7932
7933
#ifdef HAVE_GETUID
7934
/*[clinic input]
7935
os.getuid
7936
7937
Return the current process's user id.
7938
[clinic start generated code]*/
7939
7940
static PyObject *
7941
os_getuid_impl(PyObject *module)
7942
/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
7943
304
{
7944
304
    return _PyLong_FromUid(getuid());
7945
304
}
7946
#endif /* HAVE_GETUID */
7947
7948
7949
#ifdef MS_WINDOWS
7950
#define HAVE_KILL
7951
#endif /* MS_WINDOWS */
7952
7953
#ifdef HAVE_KILL
7954
/*[clinic input]
7955
os.kill
7956
7957
    pid: pid_t
7958
    signal: Py_ssize_t
7959
    /
7960
7961
Kill a process with a signal.
7962
[clinic start generated code]*/
7963
7964
static PyObject *
7965
os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7966
/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
7967
15.7k
{
7968
15.7k
    if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
  Branch (7968:9): [True: 0, False: 15.7k]
7969
0
        return NULL;
7970
0
    }
7971
15.7k
#ifndef MS_WINDOWS
7972
15.7k
    if (kill(pid, (int)signal) == -1) {
  Branch (7972:9): [True: 11, False: 15.7k]
7973
11
        return posix_error();
7974
11
    }
7975
7976
    // Check immediately if the signal was sent to the current process.
7977
    // Don't micro-optimize pid == getpid(), since PyErr_SetString() check
7978
    // is cheap.
7979
15.7k
    if (PyErr_CheckSignals()) {
  Branch (7979:9): [True: 93, False: 15.6k]
7980
93
        return NULL;
7981
93
    }
7982
7983
15.7k
    Py_RETURN_NONE;
Line
Count
Source
661
15.6k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
15.6k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
15.6k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
15.6k
#  define _Py_CAST(type, expr) ((type)(expr))
7984
#else /* !MS_WINDOWS */
7985
    PyObject *result;
7986
    DWORD sig = (DWORD)signal;
7987
    DWORD err;
7988
    HANDLE handle;
7989
7990
    /* Console processes which share a common console can be sent CTRL+C or
7991
       CTRL+BREAK events, provided they handle said events. */
7992
    if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
7993
        if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
7994
            err = GetLastError();
7995
            PyErr_SetFromWindowsErr(err);
7996
        }
7997
        else
7998
            Py_RETURN_NONE;
7999
    }
8000
8001
    /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
8002
       attempt to open and terminate the process. */
8003
    handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
8004
    if (handle == NULL) {
8005
        err = GetLastError();
8006
        return PyErr_SetFromWindowsErr(err);
8007
    }
8008
8009
    if (TerminateProcess(handle, sig) == 0) {
8010
        err = GetLastError();
8011
        result = PyErr_SetFromWindowsErr(err);
8012
    } else {
8013
        Py_INCREF(Py_None);
8014
        result = Py_None;
8015
    }
8016
8017
    CloseHandle(handle);
8018
    return result;
8019
#endif /* !MS_WINDOWS */
8020
15.7k
}
8021
#endif /* HAVE_KILL */
8022
8023
8024
#ifdef HAVE_KILLPG
8025
/*[clinic input]
8026
os.killpg
8027
8028
    pgid: pid_t
8029
    signal: int
8030
    /
8031
8032
Kill a process group with a signal.
8033
[clinic start generated code]*/
8034
8035
static PyObject *
8036
os_killpg_impl(PyObject *module, pid_t pgid, int signal)
8037
/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
8038
0
{
8039
0
    if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
  Branch (8039:9): [True: 0, False: 0]
8040
0
        return NULL;
8041
0
    }
8042
    /* XXX some man pages make the `pgid` parameter an int, others
8043
       a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
8044
       take the same type. Moreover, pid_t is always at least as wide as
8045
       int (else compilation of this module fails), which is safe. */
8046
0
    if (killpg(pgid, signal) == -1)
  Branch (8046:9): [True: 0, False: 0]
8047
0
        return posix_error();
8048
0
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8049
0
}
8050
#endif /* HAVE_KILLPG */
8051
8052
8053
#ifdef HAVE_PLOCK
8054
#ifdef HAVE_SYS_LOCK_H
8055
#include <sys/lock.h>
8056
#endif
8057
8058
/*[clinic input]
8059
os.plock
8060
    op: int
8061
    /
8062
8063
Lock program segments into memory.");
8064
[clinic start generated code]*/
8065
8066
static PyObject *
8067
os_plock_impl(PyObject *module, int op)
8068
/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
8069
{
8070
    if (plock(op) == -1)
8071
        return posix_error();
8072
    Py_RETURN_NONE;
8073
}
8074
#endif /* HAVE_PLOCK */
8075
8076
8077
#ifdef HAVE_SETUID
8078
/*[clinic input]
8079
os.setuid
8080
8081
    uid: uid_t
8082
    /
8083
8084
Set the current process's user id.
8085
[clinic start generated code]*/
8086
8087
static PyObject *
8088
os_setuid_impl(PyObject *module, uid_t uid)
8089
/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
8090
1
{
8091
1
    if (setuid(uid) < 0)
  Branch (8091:9): [True: 1, False: 0]
8092
1
        return posix_error();
8093
1
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8094
1
}
8095
#endif /* HAVE_SETUID */
8096
8097
8098
#ifdef HAVE_SETEUID
8099
/*[clinic input]
8100
os.seteuid
8101
8102
    euid: uid_t
8103
    /
8104
8105
Set the current process's effective user id.
8106
[clinic start generated code]*/
8107
8108
static PyObject *
8109
os_seteuid_impl(PyObject *module, uid_t euid)
8110
/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
8111
1
{
8112
1
    if (seteuid(euid) < 0)
  Branch (8112:9): [True: 1, False: 0]
8113
1
        return posix_error();
8114
1
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8115
1
}
8116
#endif /* HAVE_SETEUID */
8117
8118
8119
#ifdef HAVE_SETEGID
8120
/*[clinic input]
8121
os.setegid
8122
8123
    egid: gid_t
8124
    /
8125
8126
Set the current process's effective group id.
8127
[clinic start generated code]*/
8128
8129
static PyObject *
8130
os_setegid_impl(PyObject *module, gid_t egid)
8131
/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
8132
1
{
8133
1
    if (setegid(egid) < 0)
  Branch (8133:9): [True: 1, False: 0]
8134
1
        return posix_error();
8135
1
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8136
1
}
8137
#endif /* HAVE_SETEGID */
8138
8139
8140
#ifdef HAVE_SETREUID
8141
/*[clinic input]
8142
os.setreuid
8143
8144
    ruid: uid_t
8145
    euid: uid_t
8146
    /
8147
8148
Set the current process's real and effective user ids.
8149
[clinic start generated code]*/
8150
8151
static PyObject *
8152
os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
8153
/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
8154
1
{
8155
1
    if (setreuid(ruid, euid) < 0) {
  Branch (8155:9): [True: 1, False: 0]
8156
1
        return posix_error();
8157
1
    } else {
8158
0
        Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8159
0
    }
8160
1
}
8161
#endif /* HAVE_SETREUID */
8162
8163
8164
#ifdef HAVE_SETREGID
8165
/*[clinic input]
8166
os.setregid
8167
8168
    rgid: gid_t
8169
    egid: gid_t
8170
    /
8171
8172
Set the current process's real and effective group ids.
8173
[clinic start generated code]*/
8174
8175
static PyObject *
8176
os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
8177
/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
8178
1
{
8179
1
    if (setregid(rgid, egid) < 0)
  Branch (8179:9): [True: 1, False: 0]
8180
1
        return posix_error();
8181
1
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8182
1
}
8183
#endif /* HAVE_SETREGID */
8184
8185
8186
#ifdef HAVE_SETGID
8187
/*[clinic input]
8188
os.setgid
8189
    gid: gid_t
8190
    /
8191
8192
Set the current process's group id.
8193
[clinic start generated code]*/
8194
8195
static PyObject *
8196
os_setgid_impl(PyObject *module, gid_t gid)
8197
/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
8198
1
{
8199
1
    if (setgid(gid) < 0)
  Branch (8199:9): [True: 1, False: 0]
8200
1
        return posix_error();
8201
1
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8202
1
}
8203
#endif /* HAVE_SETGID */
8204
8205
8206
#ifdef HAVE_SETGROUPS
8207
/*[clinic input]
8208
os.setgroups
8209
8210
    groups: object
8211
    /
8212
8213
Set the groups of the current process to list.
8214
[clinic start generated code]*/
8215
8216
static PyObject *
8217
os_setgroups(PyObject *module, PyObject *groups)
8218
/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
8219
0
{
8220
0
    if (!PySequence_Check(groups)) {
  Branch (8220:9): [True: 0, False: 0]
8221
0
        PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
8222
0
        return NULL;
8223
0
    }
8224
0
    Py_ssize_t len = PySequence_Size(groups);
8225
0
    if (len < 0) {
  Branch (8225:9): [True: 0, False: 0]
8226
0
        return NULL;
8227
0
    }
8228
0
    if (len > MAX_GROUPS) {
Line
Count
Source
7529
0
#define MAX_GROUPS NGROUPS_MAX
  Branch (8228:9): [True: 0, False: 0]
8229
0
        PyErr_SetString(PyExc_ValueError, "too many groups");
8230
0
        return NULL;
8231
0
    }
8232
8233
0
    gid_t *grouplist = PyMem_New(gid_t, len);
Line
Count
Source
68
0
  ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL :      \
Line
Count
Source
180
0
#   define PY_SSIZE_T_MAX SSIZE_MAX
  Branch (68:5): [True: 0, False: 0]
69
0
        ( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
8234
0
    for (Py_ssize_t i = 0; i < len; i++) {
  Branch (8234:28): [True: 0, False: 0]
8235
0
        PyObject *elem;
8236
0
        elem = PySequence_GetItem(groups, i);
8237
0
        if (!elem) {
  Branch (8237:13): [True: 0, False: 0]
8238
0
            PyMem_Free(grouplist);
8239
0
            return NULL;
8240
0
        }
8241
0
        if (!PyLong_Check(elem)) {
Line
Count
Source
13
0
        PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS)
Line
Count
Source
782
0
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (8241:13): [True: 0, False: 0]
8242
0
            PyErr_SetString(PyExc_TypeError,
8243
0
                            "groups must be integers");
8244
0
            Py_DECREF(elem);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8245
0
            PyMem_Free(grouplist);
8246
0
            return NULL;
8247
0
        } else {
8248
0
            if (!_Py_Gid_Converter(elem, &grouplist[i])) {
  Branch (8248:17): [True: 0, False: 0]
8249
0
                Py_DECREF(elem);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8250
0
                PyMem_Free(grouplist);
8251
0
                return NULL;
8252
0
            }
8253
0
        }
8254
0
        Py_DECREF(elem);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8255
0
    }
8256
8257
0
    if (setgroups(len, grouplist) < 0) {
  Branch (8257:9): [True: 0, False: 0]
8258
0
        PyMem_Free(grouplist);
8259
0
        return posix_error();
8260
0
    }
8261
0
    PyMem_Free(grouplist);
8262
0
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8263
0
}
8264
#endif /* HAVE_SETGROUPS */
8265
8266
#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
8267
static PyObject *
8268
wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
8269
19
{
8270
19
    PyObject *result;
8271
19
    PyObject *struct_rusage;
8272
8273
19
    if (pid == -1)
  Branch (8273:9): [True: 0, False: 19]
8274
0
        return posix_error();
8275
8276
    // If wait succeeded but no child was ready to report status, ru will not
8277
    // have been populated.
8278
19
    if (pid == 0) {
  Branch (8278:9): [True: 17, False: 2]
8279
17
        memset(ru, 0, sizeof(*ru));
8280
17
    }
8281
8282
19
    struct_rusage = _PyImport_GetModuleAttrString("resource", "struct_rusage");
8283
19
    if (struct_rusage == NULL)
  Branch (8283:9): [True: 0, False: 19]
8284
0
        return NULL;
8285
8286
    /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
8287
19
    result = PyStructSequence_New((PyTypeObject*) struct_rusage);
8288
19
    Py_DECREF(struct_rusage);
Line
Count
Source
548
19
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8289
19
    if (!result)
  Branch (8289:9): [True: 0, False: 19]
8290
0
        return NULL;
8291
8292
19
#ifndef doubletime
8293
19
#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
8294
19
#endif
8295
8296
19
    PyStructSequence_SET_ITEM(result, 0,
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8297
19
                              PyFloat_FromDouble(doubletime(ru->ru_utime)));
8298
19
    PyStructSequence_SET_ITEM(result, 1,
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8299
19
                              PyFloat_FromDouble(doubletime(ru->ru_stime)));
8300
19
#define SET_INT(result, index, value)\
8301
266
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
8302
19
    SET_INT(result, 2, ru->ru_maxrss);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8303
19
    SET_INT(result, 3, ru->ru_ixrss);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8304
19
    SET_INT(result, 4, ru->ru_idrss);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8305
19
    SET_INT(result, 5, ru->ru_isrss);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8306
19
    SET_INT(result, 6, ru->ru_minflt);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8307
19
    SET_INT(result, 7, ru->ru_majflt);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8308
19
    SET_INT(result, 8, ru->ru_nswap);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8309
19
    SET_INT(result, 9, ru->ru_inblock);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8310
19
    SET_INT(result, 10, ru->ru_oublock);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8311
19
    SET_INT(result, 11, ru->ru_msgsnd);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8312
19
    SET_INT(result, 12, ru->ru_msgrcv);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8313
19
    SET_INT(result, 13, ru->ru_nsignals);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8314
19
    SET_INT(result, 14, ru->ru_nvcsw);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8315
19
    SET_INT(result, 15, ru->ru_nivcsw);
Line
Count
Source
8301
19
        PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Line
Count
Source
38
19
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
19
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
19
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19
#  define _Py_CAST(type, expr) ((type)(expr))
8316
19
#undef SET_INT
8317
8318
19
    if (PyErr_Occurred()) {
  Branch (8318:9): [True: 0, False: 19]
8319
0
        Py_DECREF(result);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8320
0
        return NULL;
8321
0
    }
8322
8323
19
    return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Line
Count
Source
20
19
#define Py_BuildValue                   _Py_BuildValue_SizeT
    return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Line
Count
Source
36
19
#define PyLong_FromPid PyLong_FromLong
8324
19
}
8325
#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
8326
8327
8328
#ifdef HAVE_WAIT3
8329
/*[clinic input]
8330
os.wait3
8331
8332
    options: int
8333
Wait for completion of a child process.
8334
8335
Returns a tuple of information about the child process:
8336
  (pid, status, rusage)
8337
[clinic start generated code]*/
8338
8339
static PyObject *
8340
os_wait3_impl(PyObject *module, int options)
8341
/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
8342
10
{
8343
10
    pid_t pid;
8344
10
    struct rusage ru;
8345
10
    int async_err = 0;
8346
10
    WAIT_TYPE status;
Line
Count
Source
450
10
#  define WAIT_TYPE int
8347
10
    WAIT_STATUS_INT(status) = 0;
Line
Count
Source
451
10
#  define WAIT_STATUS_INT(s) (s)
8348
8349
10
    do {
8350
10
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
10
#define Py_BEGIN_ALLOW_THREADS { \
143
10
                        PyThreadState *_save; \
144
10
                        _save = PyEval_SaveThread();
8351
10
        pid = wait3(&status, options, &ru);
8352
10
        Py_END_ALLOW_THREADS
Line
Count
Source
147
10
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
10
                 }
8353
10
    } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (8353:14): [True: 0, False: 10]
  Branch (8353:25): [True: 0, False: 0]
  Branch (8353:43): [True: 0, False: 0]
8354
10
    if (pid < 0)
  Branch (8354:9): [True: 0, False: 10]
8355
0
        return (!async_err) ? posix_error() : NULL;
  Branch (8355:16): [True: 0, False: 0]
8356
8357
10
    return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Line
Count
Source
451
10
#  define WAIT_STATUS_INT(s) (s)
8358
10
}
8359
#endif /* HAVE_WAIT3 */
8360
8361
8362
#ifdef HAVE_WAIT4
8363
/*[clinic input]
8364
8365
os.wait4
8366
8367
    pid: pid_t
8368
    options: int
8369
8370
Wait for completion of a specific child process.
8371
8372
Returns a tuple of information about the child process:
8373
  (pid, status, rusage)
8374
[clinic start generated code]*/
8375
8376
static PyObject *
8377
os_wait4_impl(PyObject *module, pid_t pid, int options)
8378
/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
8379
9
{
8380
9
    pid_t res;
8381
9
    struct rusage ru;
8382
9
    int async_err = 0;
8383
9
    WAIT_TYPE status;
Line
Count
Source
450
9
#  define WAIT_TYPE int
8384
9
    WAIT_STATUS_INT(status) = 0;
Line
Count
Source
451
9
#  define WAIT_STATUS_INT(s) (s)
8385
8386
9
    do {
8387
9
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
9
#define Py_BEGIN_ALLOW_THREADS { \
143
9
                        PyThreadState *_save; \
144
9
                        _save = PyEval_SaveThread();
8388
9
        res = wait4(pid, &status, options, &ru);
8389
9
        Py_END_ALLOW_THREADS
Line
Count
Source
147
9
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
9
                 }
8390
9
    } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (8390:14): [True: 0, False: 9]
  Branch (8390:25): [True: 0, False: 0]
  Branch (8390:43): [True: 0, False: 0]
8391
9
    if (res < 0)
  Branch (8391:9): [True: 0, False: 9]
8392
0
        return (!async_err) ? posix_error() : NULL;
  Branch (8392:16): [True: 0, False: 0]
8393
8394
9
    return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Line
Count
Source
451
9
#  define WAIT_STATUS_INT(s) (s)
8395
9
}
8396
#endif /* HAVE_WAIT4 */
8397
8398
8399
#if defined(HAVE_WAITID) && !defined(__APPLE__)
8400
/*[clinic input]
8401
os.waitid
8402
8403
    idtype: idtype_t
8404
        Must be one of be P_PID, P_PGID or P_ALL.
8405
    id: id_t
8406
        The id to wait on.
8407
    options: int
8408
        Constructed from the ORing of one or more of WEXITED, WSTOPPED
8409
        or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
8410
    /
8411
8412
Returns the result of waiting for a process or processes.
8413
8414
Returns either waitid_result or None if WNOHANG is specified and there are
8415
no children in a waitable state.
8416
[clinic start generated code]*/
8417
8418
static PyObject *
8419
os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
8420
/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
8421
1
{
8422
1
    PyObject *result;
8423
1
    int res;
8424
1
    int async_err = 0;
8425
1
    siginfo_t si;
8426
1
    si.si_pid = 0;
8427
8428
1
    do {
8429
1
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
1
#define Py_BEGIN_ALLOW_THREADS { \
143
1
                        PyThreadState *_save; \
144
1
                        _save = PyEval_SaveThread();
8430
1
        res = waitid(idtype, id, &si, options);
8431
1
        Py_END_ALLOW_THREADS
Line
Count
Source
147
1
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
1
                 }
8432
1
    } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (8432:14): [True: 0, False: 1]
  Branch (8432:25): [True: 0, False: 0]
  Branch (8432:43): [True: 0, False: 0]
8433
1
    if (res < 0)
  Branch (8433:9): [True: 0, False: 1]
8434
0
        return (!async_err) ? posix_error() : NULL;
  Branch (8434:16): [True: 0, False: 0]
8435
8436
1
    if (si.si_pid == 0)
  Branch (8436:9): [True: 0, False: 1]
8437
0
        Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8438
8439
1
    PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
8440
1
    result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
8441
1
    if (!result)
  Branch (8441:9): [True: 0, False: 1]
8442
0
        return NULL;
8443
8444
1
    PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Line
Count
Source
38
1
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
1
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
8445
1
    PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Line
Count
Source
38
1
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
1
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
8446
1
    PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
Line
Count
Source
38
1
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
1
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
8447
1
    PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
Line
Count
Source
38
1
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
1
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
8448
1
    PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
Line
Count
Source
38
1
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
1
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
8449
1
    if (PyErr_Occurred()) {
  Branch (8449:9): [True: 0, False: 1]
8450
0
        Py_DECREF(result);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8451
0
        return NULL;
8452
0
    }
8453
8454
1
    return result;
8455
1
}
8456
#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
8457
8458
8459
#if defined(HAVE_WAITPID)
8460
/*[clinic input]
8461
os.waitpid
8462
    pid: pid_t
8463
    options: int
8464
    /
8465
8466
Wait for completion of a given child process.
8467
8468
Returns a tuple of information regarding the child process:
8469
    (pid, status)
8470
8471
The options argument is ignored on Windows.
8472
[clinic start generated code]*/
8473
8474
static PyObject *
8475
os_waitpid_impl(PyObject *module, pid_t pid, int options)
8476
/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
8477
35.8k
{
8478
35.8k
    pid_t res;
8479
35.8k
    int async_err = 0;
8480
35.8k
    WAIT_TYPE status;
Line
Count
Source
450
35.8k
#  define WAIT_TYPE int
8481
35.8k
    WAIT_STATUS_INT(status) = 0;
Line
Count
Source
451
35.8k
#  define WAIT_STATUS_INT(s) (s)
8482
8483
35.8k
    do {
8484
35.8k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
35.8k
#define Py_BEGIN_ALLOW_THREADS { \
143
35.8k
                        PyThreadState *_save; \
144
35.8k
                        _save = PyEval_SaveThread();
8485
35.8k
        res = waitpid(pid, &status, options);
8486
35.8k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
35.8k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
35.8k
                 }
8487
35.8k
    } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (8487:14): [True: 3.39k, False: 32.4k]
  Branch (8487:25): [True: 2, False: 3.39k]
  Branch (8487:43): [True: 2, False: 0]
8488
35.8k
    if (res < 0)
  Branch (8488:9): [True: 3.39k, False: 32.4k]
8489
3.39k
        return (!async_err) ? posix_error() : NULL;
  Branch (8489:16): [True: 3.39k, False: 0]
8490
8491
32.4k
    return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Line
Count
Source
20
32.4k
#define Py_BuildValue                   _Py_BuildValue_SizeT
    return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Line
Count
Source
36
32.4k
#define PyLong_FromPid PyLong_FromLong
    return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Line
Count
Source
451
32.4k
#  define WAIT_STATUS_INT(s) (s)
8492
35.8k
}
8493
#elif defined(HAVE_CWAIT)
8494
/* MS C has a variant of waitpid() that's usable for most purposes. */
8495
/*[clinic input]
8496
os.waitpid
8497
    pid: intptr_t
8498
    options: int
8499
    /
8500
8501
Wait for completion of a given process.
8502
8503
Returns a tuple of information regarding the process:
8504
    (pid, status << 8)
8505
8506
The options argument is ignored on Windows.
8507
[clinic start generated code]*/
8508
8509
static PyObject *
8510
os_waitpid_impl(PyObject *module, intptr_t pid, int options)
8511
/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
8512
{
8513
    int status;
8514
    intptr_t res;
8515
    int async_err = 0;
8516
8517
    do {
8518
        Py_BEGIN_ALLOW_THREADS
8519
        _Py_BEGIN_SUPPRESS_IPH
8520
        res = _cwait(&status, pid, options);
8521
        _Py_END_SUPPRESS_IPH
8522
        Py_END_ALLOW_THREADS
8523
    } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8524
    if (res < 0)
8525
        return (!async_err) ? posix_error() : NULL;
8526
8527
    unsigned long long ustatus = (unsigned int)status;
8528
8529
    /* shift the status left a byte so this is more like the POSIX waitpid */
8530
    return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
8531
}
8532
#endif
8533
8534
8535
#ifdef HAVE_WAIT
8536
/*[clinic input]
8537
os.wait
8538
8539
Wait for completion of a child process.
8540
8541
Returns a tuple of information about the child process:
8542
    (pid, status)
8543
[clinic start generated code]*/
8544
8545
static PyObject *
8546
os_wait_impl(PyObject *module)
8547
/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
8548
0
{
8549
0
    pid_t pid;
8550
0
    int async_err = 0;
8551
0
    WAIT_TYPE status;
Line
Count
Source
450
0
#  define WAIT_TYPE int
8552
0
    WAIT_STATUS_INT(status) = 0;
Line
Count
Source
451
0
#  define WAIT_STATUS_INT(s) (s)
8553
8554
0
    do {
8555
0
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
0
#define Py_BEGIN_ALLOW_THREADS { \
143
0
                        PyThreadState *_save; \
144
0
                        _save = PyEval_SaveThread();
8556
0
        pid = wait(&status);
8557
0
        Py_END_ALLOW_THREADS
Line
Count
Source
147
0
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
0
                 }
8558
0
    } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (8558:14): [True: 0, False: 0]
  Branch (8558:25): [True: 0, False: 0]
  Branch (8558:43): [True: 0, False: 0]
8559
0
    if (pid < 0)
  Branch (8559:9): [True: 0, False: 0]
8560
0
        return (!async_err) ? posix_error() : NULL;
  Branch (8560:16): [True: 0, False: 0]
8561
8562
0
    return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Line
Count
Source
20
0
#define Py_BuildValue                   _Py_BuildValue_SizeT
    return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Line
Count
Source
36
0
#define PyLong_FromPid PyLong_FromLong
    return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Line
Count
Source
451
0
#  define WAIT_STATUS_INT(s) (s)
8563
0
}
8564
#endif /* HAVE_WAIT */
8565
8566
#if defined(__linux__) && defined(__NR_pidfd_open)
8567
/*[clinic input]
8568
os.pidfd_open
8569
  pid: pid_t
8570
  flags: unsigned_int = 0
8571
8572
Return a file descriptor referring to the process *pid*.
8573
8574
The descriptor can be used to perform process management without races and
8575
signals.
8576
[clinic start generated code]*/
8577
8578
static PyObject *
8579
os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8580
/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8581
26
{
8582
26
    int fd = syscall(__NR_pidfd_open, pid, flags);
8583
26
    if (fd < 0) {
  Branch (8583:9): [True: 1, False: 25]
8584
1
        return posix_error();
8585
1
    }
8586
25
    return PyLong_FromLong(fd);
8587
26
}
8588
#endif
8589
8590
8591
#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
8592
/*[clinic input]
8593
os.readlink
8594
8595
    path: path_t
8596
    *
8597
    dir_fd: dir_fd(requires='readlinkat') = None
8598
8599
Return a string representing the path to which the symbolic link points.
8600
8601
If dir_fd is not None, it should be a file descriptor open to a directory,
8602
and path should be relative; path will then be relative to that directory.
8603
8604
dir_fd may not be implemented on your platform.  If it is unavailable,
8605
using it will raise a NotImplementedError.
8606
[clinic start generated code]*/
8607
8608
static PyObject *
8609
os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8610
/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
8611
309
{
8612
309
#if defined(HAVE_READLINK)
8613
309
    char buffer[MAXPATHLEN+1];
8614
309
    ssize_t length;
8615
309
#ifdef HAVE_READLINKAT
8616
309
    int readlinkat_unavailable = 0;
8617
309
#endif
8618
8619
309
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
309
#define Py_BEGIN_ALLOW_THREADS { \
143
309
                        PyThreadState *_save; \
144
309
                        _save = PyEval_SaveThread();
8620
309
#ifdef HAVE_READLINKAT
8621
309
    if (dir_fd != DEFAULT_DIR_FD) {
Line
Count
Source
904
309
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (8621:9): [True: 1, False: 308]
8622
1
        if (HAVE_READLINKAT_RUNTIME) {
Line
Count
Source
173
1
#  define HAVE_READLINKAT_RUNTIME 1
  Branch (173:35): [Folded - Ignored]
8623
1
            length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8624
1
        } else {
8625
0
            readlinkat_unavailable = 1;
8626
0
        }
8627
1
    } else
8628
308
#endif
8629
308
        length = readlink(path->narrow, buffer, MAXPATHLEN);
8630
309
    Py_END_ALLOW_THREADS
Line
Count
Source
147
309
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
309
                 }
8631
8632
309
#ifdef HAVE_READLINKAT
8633
309
    if (readlinkat_unavailable) {
  Branch (8633:9): [True: 0, False: 309]
8634
0
        argument_unavailable_error(NULL, "dir_fd");
8635
0
        return NULL;
8636
0
    }
8637
309
#endif
8638
8639
309
    if (length < 0) {
  Branch (8639:9): [True: 11, False: 298]
8640
11
        return path_error(path);
8641
11
    }
8642
298
    buffer[length] = '\0';
8643
8644
298
    if (PyUnicode_Check(path->object))
Line
Count
Source
115
298
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
Line
Count
Source
782
298
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (782:41): [True: 296, False: 2]
8645
296
        return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8646
2
    else
8647
2
        return PyBytes_FromStringAndSize(buffer, length);
8648
#elif defined(MS_WINDOWS)
8649
    DWORD n_bytes_returned;
8650
    DWORD io_result = 0;
8651
    HANDLE reparse_point_handle;
8652
    char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8653
    _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
8654
    PyObject *result = NULL;
8655
8656
    /* First get a handle to the reparse point */
8657
    Py_BEGIN_ALLOW_THREADS
8658
    reparse_point_handle = CreateFileW(
8659
        path->wide,
8660
        0,
8661
        0,
8662
        0,
8663
        OPEN_EXISTING,
8664
        FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8665
        0);
8666
    if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8667
        /* New call DeviceIoControl to read the reparse point */
8668
        io_result = DeviceIoControl(
8669
            reparse_point_handle,
8670
            FSCTL_GET_REPARSE_POINT,
8671
            0, 0, /* in buffer */
8672
            target_buffer, sizeof(target_buffer),
8673
            &n_bytes_returned,
8674
            0 /* we're not using OVERLAPPED_IO */
8675
            );
8676
        CloseHandle(reparse_point_handle);
8677
    }
8678
    Py_END_ALLOW_THREADS
8679
8680
    if (io_result == 0) {
8681
        return path_error(path);
8682
    }
8683
8684
    wchar_t *name = NULL;
8685
    Py_ssize_t nameLen = 0;
8686
    if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
8687
    {
8688
        name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8689
                           rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8690
        nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8691
    }
8692
    else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8693
    {
8694
        name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8695
                           rdb->MountPointReparseBuffer.SubstituteNameOffset);
8696
        nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8697
    }
8698
    else
8699
    {
8700
        PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8701
    }
8702
    if (name) {
8703
        if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8704
            /* Our buffer is mutable, so this is okay */
8705
            name[1] = L'\\';
8706
        }
8707
        result = PyUnicode_FromWideChar(name, nameLen);
8708
        if (result && path->narrow) {
8709
            Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8710
        }
8711
    }
8712
    return result;
8713
#endif
8714
298
}
8715
#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
8716
8717
#if defined(MS_WINDOWS)
8718
8719
/* Remove the last portion of the path - return 0 on success */
8720
static int
8721
_dirnameW(WCHAR *path)
8722
{
8723
    WCHAR *ptr;
8724
    size_t length = wcsnlen_s(path, MAX_PATH);
8725
    if (length == MAX_PATH) {
8726
        return -1;
8727
    }
8728
8729
    /* walk the path from the end until a backslash is encountered */
8730
    for(ptr = path + length; ptr != path; ptr--) {
8731
        if (*ptr == L'\\' || *ptr == L'/') {
8732
            break;
8733
        }
8734
    }
8735
    *ptr = 0;
8736
    return 0;
8737
}
8738
8739
#endif
8740
8741
#ifdef HAVE_SYMLINK
8742
8743
#if defined(MS_WINDOWS)
8744
8745
/* Is this path absolute? */
8746
static int
8747
_is_absW(const WCHAR *path)
8748
{
8749
    return path[0] == L'\\' || path[0] == L'/' ||
8750
        (path[0] && path[1] == L':');
8751
}
8752
8753
/* join root and rest with a backslash - return 0 on success */
8754
static int
8755
_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8756
{
8757
    if (_is_absW(rest)) {
8758
        return wcscpy_s(dest_path, MAX_PATH, rest);
8759
    }
8760
8761
    if (wcscpy_s(dest_path, MAX_PATH, root)) {
8762
        return -1;
8763
    }
8764
8765
    if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8766
        return -1;
8767
    }
8768
8769
    return wcscat_s(dest_path, MAX_PATH, rest);
8770
}
8771
8772
/* Return True if the path at src relative to dest is a directory */
8773
static int
8774
_check_dirW(LPCWSTR src, LPCWSTR dest)
8775
{
8776
    WIN32_FILE_ATTRIBUTE_DATA src_info;
8777
    WCHAR dest_parent[MAX_PATH];
8778
    WCHAR src_resolved[MAX_PATH] = L"";
8779
8780
    /* dest_parent = os.path.dirname(dest) */
8781
    if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8782
        _dirnameW(dest_parent)) {
8783
        return 0;
8784
    }
8785
    /* src_resolved = os.path.join(dest_parent, src) */
8786
    if (_joinW(src_resolved, dest_parent, src)) {
8787
        return 0;
8788
    }
8789
    return (
8790
        GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8791
        && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8792
    );
8793
}
8794
#endif
8795
8796
8797
/*[clinic input]
8798
os.symlink
8799
    src: path_t
8800
    dst: path_t
8801
    target_is_directory: bool = False
8802
    *
8803
    dir_fd: dir_fd(requires='symlinkat')=None
8804
8805
# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8806
8807
Create a symbolic link pointing to src named dst.
8808
8809
target_is_directory is required on Windows if the target is to be
8810
  interpreted as a directory.  (On Windows, symlink requires
8811
  Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8812
  target_is_directory is ignored on non-Windows platforms.
8813
8814
If dir_fd is not None, it should be a file descriptor open to a directory,
8815
  and path should be relative; path will then be relative to that directory.
8816
dir_fd may not be implemented on your platform.
8817
  If it is unavailable, using it will raise a NotImplementedError.
8818
8819
[clinic start generated code]*/
8820
8821
static PyObject *
8822
os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
8823
                int target_is_directory, int dir_fd)
8824
/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
8825
1.27k
{
8826
#ifdef MS_WINDOWS
8827
    DWORD result;
8828
    DWORD flags = 0;
8829
8830
    /* Assumed true, set to false if detected to not be available. */
8831
    static int windows_has_symlink_unprivileged_flag = TRUE;
8832
#else
8833
1.27k
    int result;
8834
1.27k
#ifdef HAVE_SYMLINKAT
8835
1.27k
    int symlinkat_unavailable = 0;
8836
1.27k
#endif
8837
1.27k
#endif
8838
8839
1.27k
    if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
  Branch (8839:9): [True: 0, False: 1.27k]
8840
1.27k
                    dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
Line
Count
Source
904
1.27k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (8840:21): [True: 1.27k, False: 1]
8841
0
        return NULL;
8842
0
    }
8843
8844
#ifdef MS_WINDOWS
8845
8846
    if (windows_has_symlink_unprivileged_flag) {
8847
        /* Allow non-admin symlinks if system allows it. */
8848
        flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8849
    }
8850
8851
    Py_BEGIN_ALLOW_THREADS
8852
    _Py_BEGIN_SUPPRESS_IPH
8853
    /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8854
    if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8855
        flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8856
    }
8857
8858
    result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8859
    _Py_END_SUPPRESS_IPH
8860
    Py_END_ALLOW_THREADS
8861
8862
    if (windows_has_symlink_unprivileged_flag && !result &&
8863
        ERROR_INVALID_PARAMETER == GetLastError()) {
8864
8865
        Py_BEGIN_ALLOW_THREADS
8866
        _Py_BEGIN_SUPPRESS_IPH
8867
        /* This error might be caused by
8868
        SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8869
        Try again, and update windows_has_symlink_unprivileged_flag if we
8870
        are successful this time.
8871
8872
        NOTE: There is a risk of a race condition here if there are other
8873
        conditions than the flag causing ERROR_INVALID_PARAMETER, and
8874
        another process (or thread) changes that condition in between our
8875
        calls to CreateSymbolicLink.
8876
        */
8877
        flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8878
        result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8879
        _Py_END_SUPPRESS_IPH
8880
        Py_END_ALLOW_THREADS
8881
8882
        if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8883
            windows_has_symlink_unprivileged_flag = FALSE;
8884
        }
8885
    }
8886
8887
    if (!result)
8888
        return path_error2(src, dst);
8889
8890
#else
8891
8892
1.27k
    if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
  Branch (8892:10): [True: 1.27k, False: 0]
  Branch (8892:25): [True: 0, False: 1.27k]
  Branch (8892:40): [True: 0, False: 1.27k]
  Branch (8892:53): [True: 0, False: 0]
8893
0
        PyErr_SetString(PyExc_ValueError,
8894
0
            "symlink: src and dst must be the same type");
8895
0
        return NULL;
8896
0
    }
8897
8898
1.27k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
1.27k
#define Py_BEGIN_ALLOW_THREADS { \
143
1.27k
                        PyThreadState *_save; \
144
1.27k
                        _save = PyEval_SaveThread();
8899
1.27k
#ifdef HAVE_SYMLINKAT
8900
1.27k
    if (dir_fd != DEFAULT_DIR_FD) {
Line
Count
Source
904
1.27k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (8900:9): [True: 1, False: 1.27k]
8901
1
        if (HAVE_SYMLINKAT_RUNTIME) {
Line
Count
Source
174
1
#  define HAVE_SYMLINKAT_RUNTIME 1
  Branch (174:34): [Folded - Ignored]
8902
1
            result = symlinkat(src->narrow, dir_fd, dst->narrow);
8903
1
        } else {
8904
0
            symlinkat_unavailable = 1;
8905
0
        }
8906
1
    } else
8907
1.27k
#endif
8908
1.27k
        result = symlink(src->narrow, dst->narrow);
8909
1.27k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
1.27k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
1.27k
                 }
8910
8911
1.27k
#ifdef HAVE_SYMLINKAT
8912
1.27k
    if (symlinkat_unavailable) {
  Branch (8912:9): [True: 0, False: 1.27k]
8913
0
          argument_unavailable_error(NULL, "dir_fd");
8914
0
          return NULL;
8915
0
    }
8916
1.27k
#endif
8917
8918
1.27k
    if (result)
  Branch (8918:9): [True: 0, False: 1.27k]
8919
0
        return path_error2(src, dst);
8920
1.27k
#endif
8921
8922
1.27k
    Py_RETURN_NONE;
Line
Count
Source
661
1.27k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1.27k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1.27k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1.27k
#  define _Py_CAST(type, expr) ((type)(expr))
8923
1.27k
}
8924
#endif /* HAVE_SYMLINK */
8925
8926
8927
8928
8929
static PyStructSequence_Field times_result_fields[] = {
8930
    {"user",    "user time"},
8931
    {"system",   "system time"},
8932
    {"children_user",    "user time of children"},
8933
    {"children_system",    "system time of children"},
8934
    {"elapsed",    "elapsed time since an arbitrary point in the past"},
8935
    {NULL}
8936
};
8937
8938
PyDoc_STRVAR(times_result__doc__,
8939
"times_result: Result from os.times().\n\n\
8940
This object may be accessed either as a tuple of\n\
8941
  (user, system, children_user, children_system, elapsed),\n\
8942
or via the attributes user, system, children_user, children_system,\n\
8943
and elapsed.\n\
8944
\n\
8945
See os.times for more information.");
8946
8947
static PyStructSequence_Desc times_result_desc = {
8948
    "times_result", /* name */
8949
    times_result__doc__, /* doc */
8950
    times_result_fields,
8951
    5
8952
};
8953
8954
#ifdef MS_WINDOWS
8955
#define HAVE_TIMES  /* mandatory, for the method table */
8956
#endif
8957
8958
#ifdef HAVE_TIMES
8959
8960
static PyObject *
8961
build_times_result(PyObject *module, double user, double system,
8962
    double children_user, double children_system,
8963
    double elapsed)
8964
2
{
8965
2
    PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
8966
2
    PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
8967
2
    if (value == NULL)
  Branch (8967:9): [True: 0, False: 2]
8968
0
        return NULL;
8969
8970
2
#define SET(i, field) \
8971
10
    { \
8972
10
    PyObject *o = PyFloat_FromDouble(field); \
8973
10
    if (!o) { \
8974
0
        Py_DECREF(value); \
8975
0
        return NULL; \
8976
0
    } \
8977
10
    PyStructSequence_SET_ITEM(value, i, o); \
8978
10
    } \
8979
2
8980
4
    SET(0, user);
Line
Count
Source
8971
2
    { \
8972
2
    PyObject *o = PyFloat_FromDouble(field); \
8973
2
    if (!o) { \
  Branch (8973:9): [True: 0, False: 2]
8974
0
        Py_DECREF(value); \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8975
0
        return NULL; \
8976
0
    } \
8977
2
    PyStructSequence_SET_ITEM(value, i, o); \
Line
Count
Source
38
2
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
2
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
8978
2
    } \
8981
4
    SET(1, system);
Line
Count
Source
8971
2
    { \
8972
2
    PyObject *o = PyFloat_FromDouble(field); \
8973
2
    if (!o) { \
  Branch (8973:9): [True: 0, False: 2]
8974
0
        Py_DECREF(value); \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8975
0
        return NULL; \
8976
0
    } \
8977
2
    PyStructSequence_SET_ITEM(value, i, o); \
Line
Count
Source
38
2
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
2
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
8978
2
    } \
8982
2
    SET(2, children_user);
Line
Count
Source
8971
2
    { \
8972
2
    PyObject *o = PyFloat_FromDouble(field); \
8973
2
    if (!o) { \
  Branch (8973:9): [True: 0, False: 2]
8974
0
        Py_DECREF(value); \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8975
0
        return NULL; \
8976
0
    } \
8977
2
    PyStructSequence_SET_ITEM(value, i, o); \
Line
Count
Source
38
2
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
2
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
8978
2
    } \
8983
2
    SET(3, children_system);
Line
Count
Source
8971
2
    { \
8972
2
    PyObject *o = PyFloat_FromDouble(field); \
8973
2
    if (!o) { \
  Branch (8973:9): [True: 0, False: 2]
8974
0
        Py_DECREF(value); \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8975
0
        return NULL; \
8976
0
    } \
8977
2
    PyStructSequence_SET_ITEM(value, i, o); \
Line
Count
Source
38
2
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
2
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
8978
2
    } \
8984
2
    SET(4, elapsed);
Line
Count
Source
8971
2
    { \
8972
2
    PyObject *o = PyFloat_FromDouble(field); \
8973
2
    if (!o) { \
  Branch (8973:9): [True: 0, False: 2]
8974
0
        Py_DECREF(value); \
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
8975
0
        return NULL; \
8976
0
    } \
8977
2
    PyStructSequence_SET_ITEM(value, i, o); \
Line
Count
Source
38
2
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
2
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
8978
2
    } \
8985
8986
2
#undef SET
8987
8988
2
    return value;
8989
2
}
8990
8991
8992
#ifndef MS_WINDOWS
8993
#define NEED_TICKS_PER_SECOND
8994
static long ticks_per_second = -1;
8995
#endif /* MS_WINDOWS */
8996
8997
/*[clinic input]
8998
os.times
8999
9000
Return a collection containing process timing information.
9001
9002
The object returned behaves like a named tuple with these fields:
9003
  (utime, stime, cutime, cstime, elapsed_time)
9004
All fields are floating point numbers.
9005
[clinic start generated code]*/
9006
9007
static PyObject *
9008
os_times_impl(PyObject *module)
9009
/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
9010
#ifdef MS_WINDOWS
9011
{
9012
    FILETIME create, exit, kernel, user;
9013
    HANDLE hProc;
9014
    hProc = GetCurrentProcess();
9015
    GetProcessTimes(hProc, &create, &exit, &kernel, &user);
9016
    /* The fields of a FILETIME structure are the hi and lo part
9017
       of a 64-bit value expressed in 100 nanosecond units.
9018
       1e7 is one second in such units; 1e-7 the inverse.
9019
       429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
9020
    */
9021
    return build_times_result(module,
9022
        (double)(user.dwHighDateTime*429.4967296 +
9023
                 user.dwLowDateTime*1e-7),
9024
        (double)(kernel.dwHighDateTime*429.4967296 +
9025
                 kernel.dwLowDateTime*1e-7),
9026
        (double)0,
9027
        (double)0,
9028
        (double)0);
9029
}
9030
#else /* MS_WINDOWS */
9031
2
{
9032
9033
9034
2
    struct tms t;
9035
2
    clock_t c;
9036
2
    errno = 0;
9037
2
    c = times(&t);
9038
2
    if (c == (clock_t) -1)
  Branch (9038:9): [True: 0, False: 2]
9039
0
        return posix_error();
9040
2
    return build_times_result(module,
9041
2
                         (double)t.tms_utime / ticks_per_second,
9042
2
                         (double)t.tms_stime / ticks_per_second,
9043
2
                         (double)t.tms_cutime / ticks_per_second,
9044
2
                         (double)t.tms_cstime / ticks_per_second,
9045
2
                         (double)c / ticks_per_second);
9046
2
}
9047
#endif /* MS_WINDOWS */
9048
#endif /* HAVE_TIMES */
9049
9050
9051
#ifdef HAVE_GETSID
9052
/*[clinic input]
9053
os.getsid
9054
9055
    pid: pid_t
9056
    /
9057
9058
Call the system call getsid(pid) and return the result.
9059
[clinic start generated code]*/
9060
9061
static PyObject *
9062
os_getsid_impl(PyObject *module, pid_t pid)
9063
/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
9064
8
{
9065
8
    int sid;
9066
8
    sid = getsid(pid);
9067
8
    if (sid < 0)
  Branch (9067:9): [True: 0, False: 8]
9068
0
        return posix_error();
9069
8
    return PyLong_FromLong((long)sid);
9070
8
}
9071
#endif /* HAVE_GETSID */
9072
9073
9074
#ifdef HAVE_SETSID
9075
/*[clinic input]
9076
os.setsid
9077
9078
Call the system call setsid().
9079
[clinic start generated code]*/
9080
9081
static PyObject *
9082
os_setsid_impl(PyObject *module)
9083
/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
9084
0
{
9085
0
    if (setsid() < 0)
  Branch (9085:9): [True: 0, False: 0]
9086
0
        return posix_error();
9087
0
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
9088
0
}
9089
#endif /* HAVE_SETSID */
9090
9091
9092
#ifdef HAVE_SETPGID
9093
/*[clinic input]
9094
os.setpgid
9095
9096
    pid: pid_t
9097
    pgrp: pid_t
9098
    /
9099
9100
Call the system call setpgid(pid, pgrp).
9101
[clinic start generated code]*/
9102
9103
static PyObject *
9104
os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
9105
/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
9106
0
{
9107
0
    if (setpgid(pid, pgrp) < 0)
  Branch (9107:9): [True: 0, False: 0]
9108
0
        return posix_error();
9109
0
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
9110
0
}
9111
#endif /* HAVE_SETPGID */
9112
9113
9114
#ifdef HAVE_TCGETPGRP
9115
/*[clinic input]
9116
os.tcgetpgrp
9117
9118
    fd: int
9119
    /
9120
9121
Return the process group associated with the terminal specified by fd.
9122
[clinic start generated code]*/
9123
9124
static PyObject *
9125
os_tcgetpgrp_impl(PyObject *module, int fd)
9126
/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
9127
1
{
9128
1
    pid_t pgid = tcgetpgrp(fd);
9129
1
    if (pgid < 0)
  Branch (9129:9): [True: 1, False: 0]
9130
1
        return posix_error();
9131
0
    return PyLong_FromPid(pgid);
Line
Count
Source
36
0
#define PyLong_FromPid PyLong_FromLong
9132
1
}
9133
#endif /* HAVE_TCGETPGRP */
9134
9135
9136
#ifdef HAVE_TCSETPGRP
9137
/*[clinic input]
9138
os.tcsetpgrp
9139
9140
    fd: int
9141
    pgid: pid_t
9142
    /
9143
9144
Set the process group associated with the terminal specified by fd.
9145
[clinic start generated code]*/
9146
9147
static PyObject *
9148
os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
9149
/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
9150
1
{
9151
1
    if (tcsetpgrp(fd, pgid) < 0)
  Branch (9151:9): [True: 1, False: 0]
9152
1
        return posix_error();
9153
1
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
9154
1
}
9155
#endif /* HAVE_TCSETPGRP */
9156
9157
/* Functions acting on file descriptors */
9158
9159
#ifdef O_CLOEXEC
9160
extern int _Py_open_cloexec_works;
9161
#endif
9162
9163
9164
/*[clinic input]
9165
os.open -> int
9166
    path: path_t
9167
    flags: int
9168
    mode: int = 0o777
9169
    *
9170
    dir_fd: dir_fd(requires='openat') = None
9171
9172
# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
9173
9174
Open a file for low level IO.  Returns a file descriptor (integer).
9175
9176
If dir_fd is not None, it should be a file descriptor open to a directory,
9177
  and path should be relative; path will then be relative to that directory.
9178
dir_fd may not be implemented on your platform.
9179
  If it is unavailable, using it will raise a NotImplementedError.
9180
[clinic start generated code]*/
9181
9182
static int
9183
os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
9184
/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
9185
22.7k
{
9186
22.7k
    int fd;
9187
22.7k
    int async_err = 0;
9188
22.7k
#ifdef HAVE_OPENAT
9189
22.7k
    int openat_unavailable = 0;
9190
22.7k
#endif
9191
9192
22.7k
#ifdef O_CLOEXEC
9193
22.7k
    int *atomic_flag_works = &_Py_open_cloexec_works;
9194
#elif !defined(MS_WINDOWS)
9195
    int *atomic_flag_works = NULL;
9196
#endif
9197
9198
#ifdef MS_WINDOWS
9199
    flags |= O_NOINHERIT;
9200
#elif defined(O_CLOEXEC)
9201
22.7k
    flags |= O_CLOEXEC;
9202
22.7k
#endif
9203
9204
22.7k
    if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
Line
Count
Source
654
22.7k
#define Py_None (&_Py_NoneStruct)
  Branch (9204:9): [True: 0, False: 22.7k]
9205
0
        return -1;
9206
0
    }
9207
9208
22.7k
    _Py_BEGIN_SUPPRESS_IPH
9209
22.7k
    do {
9210
22.7k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
22.7k
#define Py_BEGIN_ALLOW_THREADS { \
143
22.7k
                        PyThreadState *_save; \
144
22.7k
                        _save = PyEval_SaveThread();
9211
#ifdef MS_WINDOWS
9212
        fd = _wopen(path->wide, flags, mode);
9213
#else
9214
22.7k
#ifdef HAVE_OPENAT
9215
22.7k
        if (dir_fd != DEFAULT_DIR_FD) {
Line
Count
Source
904
22.7k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (9215:13): [True: 9.61k, False: 13.1k]
9216
9.61k
            if (HAVE_OPENAT_RUNTIME) {
Line
Count
Source
172
9.61k
#  define HAVE_OPENAT_RUNTIME 1
  Branch (172:31): [Folded - Ignored]
9217
9.61k
                fd = openat(dir_fd, path->narrow, flags, mode);
9218
9219
9.61k
            } else {
9220
0
                openat_unavailable = 1;
9221
0
                fd = -1;
9222
0
            }
9223
9.61k
        } else
9224
13.1k
#endif /* HAVE_OPENAT */
9225
13.1k
            fd = open(path->narrow, flags, mode);
9226
22.7k
#endif /* !MS_WINDOWS */
9227
22.7k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
22.7k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
22.7k
                 }
9228
22.7k
    } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (9228:14): [True: 733, False: 22.0k]
  Branch (9228:24): [True: 0, False: 733]
  Branch (9228:42): [True: 0, False: 0]
9229
22.7k
    _Py_END_SUPPRESS_IPH
9230
9231
22.7k
#ifdef HAVE_OPENAT
9232
22.7k
    if (openat_unavailable) {
  Branch (9232:9): [True: 0, False: 22.7k]
9233
0
        argument_unavailable_error(NULL, "dir_fd");
9234
0
        return -1;
9235
0
    }
9236
22.7k
#endif
9237
9238
22.7k
    if (fd < 0) {
  Branch (9238:9): [True: 733, False: 22.0k]
9239
733
        if (!async_err)
  Branch (9239:13): [True: 733, False: 0]
9240
733
            PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
9241
733
        return -1;
9242
733
    }
9243
9244
22.0k
#ifndef MS_WINDOWS
9245
22.0k
    if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
  Branch (9245:9): [True: 0, False: 22.0k]
9246
0
        close(fd);
9247
0
        return -1;
9248
0
    }
9249
22.0k
#endif
9250
9251
22.0k
    return fd;
9252
22.0k
}
9253
9254
9255
/*[clinic input]
9256
os.close
9257
9258
    fd: int
9259
9260
Close a file descriptor.
9261
[clinic start generated code]*/
9262
9263
static PyObject *
9264
os_close_impl(PyObject *module, int fd)
9265
/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
9266
52.1k
{
9267
52.1k
    int res;
9268
    /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
9269
     * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
9270
     * for more details.
9271
     */
9272
52.1k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
52.1k
#define Py_BEGIN_ALLOW_THREADS { \
143
52.1k
                        PyThreadState *_save; \
144
52.1k
                        _save = PyEval_SaveThread();
9273
52.1k
    _Py_BEGIN_SUPPRESS_IPH
9274
52.1k
    res = close(fd);
9275
52.1k
    _Py_END_SUPPRESS_IPH
9276
52.1k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
52.1k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
52.1k
                 }
9277
52.1k
    if (res < 0)
  Branch (9277:9): [True: 25, False: 52.0k]
9278
25
        return posix_error();
9279
52.1k
    Py_RETURN_NONE;
Line
Count
Source
661
52.0k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
52.0k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
52.0k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
52.0k
#  define _Py_CAST(type, expr) ((type)(expr))
9280
52.1k
}
9281
9282
/*[clinic input]
9283
os.closerange
9284
9285
    fd_low: int
9286
    fd_high: int
9287
    /
9288
9289
Closes all file descriptors in [fd_low, fd_high), ignoring errors.
9290
[clinic start generated code]*/
9291
9292
static PyObject *
9293
os_closerange_impl(PyObject *module, int fd_low, int fd_high)
9294
/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
9295
0
{
9296
0
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
0
#define Py_BEGIN_ALLOW_THREADS { \
143
0
                        PyThreadState *_save; \
144
0
                        _save = PyEval_SaveThread();
9297
0
    _Py_closerange(fd_low, fd_high - 1);
9298
0
    Py_END_ALLOW_THREADS
Line
Count
Source
147
0
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
0
                 }
9299
0
    Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
9300
0
}
9301
9302
9303
/*[clinic input]
9304
os.dup -> int
9305
9306
    fd: int
9307
    /
9308
9309
Return a duplicate of a file descriptor.
9310
[clinic start generated code]*/
9311
9312
static int
9313
os_dup_impl(PyObject *module, int fd)
9314
/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
9315
898
{
9316
898
    return _Py_dup(fd);
9317
898
}
9318
9319
9320
/*[clinic input]
9321
os.dup2 -> int
9322
    fd: int
9323
    fd2: int
9324
    inheritable: bool=True
9325
9326
Duplicate file descriptor.
9327
[clinic start generated code]*/
9328
9329
static int
9330
os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
9331
/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
9332
163
{
9333
163
    int res = 0;
9334
163
#if defined(HAVE_DUP3) && \
9335
163
    !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
9336
    /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
9337
163
    static int dup3_works = -1;
9338
163
#endif
9339
9340
163
    if (fd < 0 || fd2 < 0) {
  Branch (9340:9): [True: 0, False: 163]
  Branch (9340:19): [True: 0, False: 163]
9341
0
        posix_error();
9342
0
        return -1;
9343
0
    }
9344
9345
    /* dup2() can fail with EINTR if the target FD is already open, because it
9346
     * then has to be closed. See os_close_impl() for why we don't handle EINTR
9347
     * upon close(), and therefore below.
9348
     */
9349
#ifdef MS_WINDOWS
9350
    Py_BEGIN_ALLOW_THREADS
9351
    _Py_BEGIN_SUPPRESS_IPH
9352
    res = dup2(fd, fd2);
9353
    _Py_END_SUPPRESS_IPH
9354
    Py_END_ALLOW_THREADS
9355
    if (res < 0) {
9356
        posix_error();
9357
        return -1;
9358
    }
9359
    res = fd2; // msvcrt dup2 returns 0 on success.
9360
9361
    /* Character files like console cannot be make non-inheritable */
9362
    if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9363
        close(fd2);
9364
        return -1;
9365
    }
9366
9367
#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
9368
    Py_BEGIN_ALLOW_THREADS
9369
    if (!inheritable)
9370
        res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
9371
    else
9372
        res = dup2(fd, fd2);
9373
    Py_END_ALLOW_THREADS
9374
    if (res < 0) {
9375
        posix_error();
9376
        return -1;
9377
    }
9378
9379
#else
9380
9381
163
#ifdef HAVE_DUP3
9382
163
    if (!inheritable && dup3_works != 0) {
  Branch (9382:9): [True: 1, False: 162]
  Branch (9382:25): [True: 1, False: 0]
9383
1
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
1
#define Py_BEGIN_ALLOW_THREADS { \
143
1
                        PyThreadState *_save; \
144
1
                        _save = PyEval_SaveThread();
9384
1
        res = dup3(fd, fd2, O_CLOEXEC);
9385
1
        Py_END_ALLOW_THREADS
Line
Count
Source
147
1
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
1
                 }
9386
1
        if (res < 0) {
  Branch (9386:13): [True: 0, False: 1]
9387
0
            if (dup3_works == -1)
  Branch (9387:17): [True: 0, False: 0]
9388
0
                dup3_works = (errno != ENOSYS);
9389
0
            if (dup3_works) {
  Branch (9389:17): [True: 0, False: 0]
9390
0
                posix_error();
9391
0
                return -1;
9392
0
            }
9393
0
        }
9394
1
    }
9395
9396
163
    if (inheritable || dup3_works == 0)
  Branch (9396:9): [True: 162, False: 1]
  Branch (9396:24): [True: 0, False: 1]
9397
162
    {
9398
162
#endif
9399
162
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
162
#define Py_BEGIN_ALLOW_THREADS { \
143
162
                        PyThreadState *_save; \
144
162
                        _save = PyEval_SaveThread();
9400
162
        res = dup2(fd, fd2);
9401
162
        Py_END_ALLOW_THREADS
Line
Count
Source
147
162
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
162
                 }
9402
162
        if (res < 0) {
  Branch (9402:13): [True: 1, False: 161]
9403
1
            posix_error();
9404
1
            return -1;
9405
1
        }
9406
9407
161
        if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
  Branch (9407:13): [True: 0, False: 161]
  Branch (9407:29): [True: 0, False: 0]
9408
0
            close(fd2);
9409
0
            return -1;
9410
0
        }
9411
161
#ifdef HAVE_DUP3
9412
161
    }
9413
162
#endif
9414
9415
162
#endif
9416
9417
162
    return res;
9418
163
}
9419
9420
9421
#ifdef HAVE_LOCKF
9422
/*[clinic input]
9423
os.lockf
9424
9425
    fd: int
9426
        An open file descriptor.
9427
    command: int
9428
        One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
9429
    length: Py_off_t
9430
        The number of bytes to lock, starting at the current position.
9431
    /
9432
9433
Apply, test or remove a POSIX lock on an open file descriptor.
9434
9435
[clinic start generated code]*/
9436
9437
static PyObject *
9438
os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
9439
/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
9440
2
{
9441
2
    int res;
9442
9443
2
    if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
  Branch (9443:9): [True: 0, False: 2]
9444
0
        return NULL;
9445
0
    }
9446
9447
2
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
2
#define Py_BEGIN_ALLOW_THREADS { \
143
2
                        PyThreadState *_save; \
144
2
                        _save = PyEval_SaveThread();
9448
2
    res = lockf(fd, command, length);
9449
2
    Py_END_ALLOW_THREADS
Line
Count
Source
147
2
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
2
                 }
9450
9451
2
    if (res < 0)
  Branch (9451:9): [True: 0, False: 2]
9452
0
        return posix_error();
9453
9454
2
    Py_RETURN_NONE;
Line
Count
Source
661
2
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
2
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
9455
2
}
9456
#endif /* HAVE_LOCKF */
9457
9458
9459
/*[clinic input]
9460
os.lseek -> Py_off_t
9461
9462
    fd: int
9463
    position: Py_off_t
9464
    how: int
9465
    /
9466
9467
Set the position of a file descriptor.  Return the new position.
9468
9469
Return the new cursor position in number of bytes
9470
relative to the beginning of the file.
9471
[clinic start generated code]*/
9472
9473
static Py_off_t
9474
os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
9475
/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
9476
8.38k
{
9477
8.38k
    Py_off_t result;
9478
9479
8.38k
#ifdef SEEK_SET
9480
    /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
9481
8.38k
    switch (how) {
  Branch (9481:13): [True: 12, False: 8.37k]
9482
2.04k
        case 0: how = SEEK_SET; break;
  Branch (9482:9): [True: 2.04k, False: 6.34k]
9483
6.24k
        case 1: how = SEEK_CUR; break;
  Branch (9483:9): [True: 6.24k, False: 2.14k]
9484
86
        case 2: how = SEEK_END; break;
  Branch (9484:9): [True: 86, False: 8.30k]
9485
8.38k
    }
9486
8.38k
#endif /* SEEK_END */
9487
9488
8.38k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
8.38k
#define Py_BEGIN_ALLOW_THREADS { \
143
8.38k
                        PyThreadState *_save; \
144
8.38k
                        _save = PyEval_SaveThread();
9489
8.38k
    _Py_BEGIN_SUPPRESS_IPH
9490
#ifdef MS_WINDOWS
9491
    result = _lseeki64(fd, position, how);
9492
#else
9493
8.38k
    result = lseek(fd, position, how);
9494
8.38k
#endif
9495
8.38k
    _Py_END_SUPPRESS_IPH
9496
8.38k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
8.38k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
8.38k
                 }
9497
8.38k
    if (result < 0)
  Branch (9497:9): [True: 32, False: 8.35k]
9498
32
        posix_error();
9499
9500
8.38k
    return result;
9501
8.38k
}
9502
9503
9504
/*[clinic input]
9505
os.read
9506
    fd: int
9507
    length: Py_ssize_t
9508
    /
9509
9510
Read from a file descriptor.  Returns a bytes object.
9511
[clinic start generated code]*/
9512
9513
static PyObject *
9514
os_read_impl(PyObject *module, int fd, Py_ssize_t length)
9515
/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
9516
612k
{
9517
612k
    Py_ssize_t n;
9518
612k
    PyObject *buffer;
9519
9520
612k
    if (length < 0) {
  Branch (9520:9): [True: 0, False: 612k]
9521
0
        errno = EINVAL;
9522
0
        return posix_error();
9523
0
    }
9524
9525
612k
    length = Py_MIN(length, _PY_READ_MAX);
Line
Count
Source
24
612k
#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x))
  Branch (24:23): [True: 0, False: 612k]
9526
9527
612k
    buffer = PyBytes_FromStringAndSize((char *)NULL, length);
9528
612k
    if (buffer == NULL)
  Branch (9528:9): [True: 0, False: 612k]
9529
0
        return NULL;
9530
9531
612k
    n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
Line
Count
Source
39
612k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
612k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
612k
#  define _Py_CAST(type, expr) ((type)(expr))
9532
612k
    if (n == -1) {
  Branch (9532:9): [True: 25, False: 612k]
9533
25
        Py_DECREF(buffer);
Line
Count
Source
548
25
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
25
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
25
#  define _Py_CAST(type, expr) ((type)(expr))
9534
25
        return NULL;
9535
25
    }
9536
9537
612k
    if (n != length)
  Branch (9537:9): [True: 484k, False: 127k]
9538
484k
        _PyBytes_Resize(&buffer, n);
9539
9540
612k
    return buffer;
9541
612k
}
9542
9543
#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
9544
                                || defined(__APPLE__))) \
9545
    || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9546
    || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9547
static int
9548
iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
9549
9
{
9550
9
    Py_ssize_t i, j;
9551
9552
9
    *iov = PyMem_New(struct iovec, cnt);
Line
Count
Source
68
9
  ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL :      \
Line
Count
Source
180
9
#   define PY_SSIZE_T_MAX SSIZE_MAX
  Branch (68:5): [True: 0, False: 9]
69
9
        ( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
9553
9
    if (*iov == NULL) {
  Branch (9553:9): [True: 0, False: 9]
9554
0
        PyErr_NoMemory();
9555
0
        return -1;
9556
0
    }
9557
9558
9
    *buf = PyMem_New(Py_buffer, cnt);
Line
Count
Source
68
9
  ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL :      \
Line
Count
Source
180
9
#   define PY_SSIZE_T_MAX SSIZE_MAX
  Branch (68:5): [True: 0, False: 9]
69
9
        ( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
9559
9
    if (*buf == NULL) {
  Branch (9559:9): [True: 0, False: 9]
9560
0
        PyMem_Free(*iov);
9561
0
        PyErr_NoMemory();
9562
0
        return -1;
9563
0
    }
9564
9565
26
    for (i = 0; i < cnt; i++) {
  Branch (9565:17): [True: 17, False: 9]
9566
17
        PyObject *item = PySequence_GetItem(seq, i);
9567
17
        if (item == NULL)
  Branch (9567:13): [True: 0, False: 17]
9568
0
            goto fail;
9569
17
        if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
  Branch (9569:13): [True: 0, False: 17]
9570
0
            Py_DECREF(item);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
9571
0
            goto fail;
9572
0
        }
9573
17
        Py_DECREF(item);
Line
Count
Source
548
17
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
17
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
17
#  define _Py_CAST(type, expr) ((type)(expr))
9574
17
        (*iov)[i].iov_base = (*buf)[i].buf;
9575
17
        (*iov)[i].iov_len = (*buf)[i].len;
9576
17
    }
9577
9
    return 0;
9578
9579
0
fail:
9580
0
    PyMem_Free(*iov);
9581
0
    for (j = 0; j < i; j++) {
  Branch (9581:17): [True: 0, False: 0]
9582
0
        PyBuffer_Release(&(*buf)[j]);
9583
0
    }
9584
0
    PyMem_Free(*buf);
9585
0
    return -1;
9586
9
}
9587
9588
static void
9589
iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9590
9
{
9591
9
    int i;
9592
9
    PyMem_Free(iov);
9593
26
    for (i = 0; i < cnt; i++) {
  Branch (9593:17): [True: 17, False: 9]
9594
17
        PyBuffer_Release(&buf[i]);
9595
17
    }
9596
9
    PyMem_Free(buf);
9597
9
}
9598
#endif
9599
9600
9601
#ifdef HAVE_READV
9602
/*[clinic input]
9603
os.readv -> Py_ssize_t
9604
9605
    fd: int
9606
    buffers: object
9607
    /
9608
9609
Read from a file descriptor fd into an iterable of buffers.
9610
9611
The buffers should be mutable buffers accepting bytes.
9612
readv will transfer data into each buffer until it is full
9613
and then move on to the next buffer in the sequence to hold
9614
the rest of the data.
9615
9616
readv returns the total number of bytes read,
9617
which may be less than the total capacity of all the buffers.
9618
[clinic start generated code]*/
9619
9620
static Py_ssize_t
9621
os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9622
/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
9623
3
{
9624
3
    Py_ssize_t cnt, n;
9625
3
    int async_err = 0;
9626
3
    struct iovec *iov;
9627
3
    Py_buffer *buf;
9628
9629
3
    if (!PySequence_Check(buffers)) {
  Branch (9629:9): [True: 0, False: 3]
9630
0
        PyErr_SetString(PyExc_TypeError,
9631
0
            "readv() arg 2 must be a sequence");
9632
0
        return -1;
9633
0
    }
9634
9635
3
    cnt = PySequence_Size(buffers);
9636
3
    if (cnt < 0)
  Branch (9636:9): [True: 0, False: 3]
9637
0
        return -1;
9638
9639
3
    if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
Line
Count
Source
106
3
#define PyBUF_WRITABLE 0x0001
  Branch (9639:9): [True: 0, False: 3]
9640
0
        return -1;
9641
9642
3
    do {
9643
3
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
3
#define Py_BEGIN_ALLOW_THREADS { \
143
3
                        PyThreadState *_save; \
144
3
                        _save = PyEval_SaveThread();
9644
3
        n = readv(fd, iov, cnt);
9645
3
        Py_END_ALLOW_THREADS
Line
Count
Source
147
3
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
3
                 }
9646
3
    } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (9646:14): [True: 1, False: 2]
  Branch (9646:23): [True: 0, False: 1]
  Branch (9646:41): [True: 0, False: 0]
9647
9648
3
    iov_cleanup(iov, buf, cnt);
9649
3
    if (n < 0) {
  Branch (9649:9): [True: 1, False: 2]
9650
1
        if (!async_err)
  Branch (9650:13): [True: 1, False: 0]
9651
1
            posix_error();
9652
1
        return -1;
9653
1
    }
9654
9655
2
    return n;
9656
3
}
9657
#endif /* HAVE_READV */
9658
9659
9660
#ifdef HAVE_PREAD
9661
/*[clinic input]
9662
os.pread
9663
9664
    fd: int
9665
    length: Py_ssize_t
9666
    offset: Py_off_t
9667
    /
9668
9669
Read a number of bytes from a file descriptor starting at a particular offset.
9670
9671
Read length bytes from file descriptor fd, starting at offset bytes from
9672
the beginning of the file.  The file offset remains unchanged.
9673
[clinic start generated code]*/
9674
9675
static PyObject *
9676
os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9677
/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
9678
1
{
9679
1
    Py_ssize_t n;
9680
1
    int async_err = 0;
9681
1
    PyObject *buffer;
9682
9683
1
    if (length < 0) {
  Branch (9683:9): [True: 0, False: 1]
9684
0
        errno = EINVAL;
9685
0
        return posix_error();
9686
0
    }
9687
1
    buffer = PyBytes_FromStringAndSize((char *)NULL, length);
9688
1
    if (buffer == NULL)
  Branch (9688:9): [True: 0, False: 1]
9689
0
        return NULL;
9690
9691
1
    do {
9692
1
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
1
#define Py_BEGIN_ALLOW_THREADS { \
143
1
                        PyThreadState *_save; \
144
1
                        _save = PyEval_SaveThread();
9693
1
        _Py_BEGIN_SUPPRESS_IPH
9694
1
        n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Line
Count
Source
39
1
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
9695
1
        _Py_END_SUPPRESS_IPH
9696
1
        Py_END_ALLOW_THREADS
Line
Count
Source
147
1
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
1
                 }
9697
1
    } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (9697:14): [True: 0, False: 1]
  Branch (9697:23): [True: 0, False: 0]
  Branch (9697:41): [True: 0, False: 0]
9698
9699
1
    if (n < 0) {
  Branch (9699:9): [True: 0, False: 1]
9700
0
        Py_DECREF(buffer);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
9701
0
        return (!async_err) ? posix_error() : NULL;
  Branch (9701:16): [True: 0, False: 0]
9702
0
    }
9703
1
    if (n != length)
  Branch (9703:9): [True: 0, False: 1]
9704
0
        _PyBytes_Resize(&buffer, n);
9705
1
    return buffer;
9706
1
}
9707
#endif /* HAVE_PREAD */
9708
9709
#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9710
/*[clinic input]
9711
os.preadv -> Py_ssize_t
9712
9713
    fd: int
9714
    buffers: object
9715
    offset: Py_off_t
9716
    flags: int = 0
9717
    /
9718
9719
Reads from a file descriptor into a number of mutable bytes-like objects.
9720
9721
Combines the functionality of readv() and pread(). As readv(), it will
9722
transfer data into each buffer until it is full and then move on to the next
9723
buffer in the sequence to hold the rest of the data. Its fourth argument,
9724
specifies the file offset at which the input operation is to be performed. It
9725
will return the total number of bytes read (which can be less than the total
9726
capacity of all the objects).
9727
9728
The flags argument contains a bitwise OR of zero or more of the following flags:
9729
9730
- RWF_HIPRI
9731
- RWF_NOWAIT
9732
9733
Using non-zero flags requires Linux 4.6 or newer.
9734
[clinic start generated code]*/
9735
9736
static Py_ssize_t
9737
os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9738
               int flags)
9739
/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9740
2
{
9741
2
    Py_ssize_t cnt, n;
9742
2
    int async_err = 0;
9743
2
    struct iovec *iov;
9744
2
    Py_buffer *buf;
9745
9746
2
    if (!PySequence_Check(buffers)) {
  Branch (9746:9): [True: 0, False: 2]
9747
0
        PyErr_SetString(PyExc_TypeError,
9748
0
            "preadv2() arg 2 must be a sequence");
9749
0
        return -1;
9750
0
    }
9751
9752
2
    cnt = PySequence_Size(buffers);
9753
2
    if (cnt < 0) {
  Branch (9753:9): [True: 0, False: 2]
9754
0
        return -1;
9755
0
    }
9756
9757
#ifndef HAVE_PREADV2
9758
    if(flags != 0) {
9759
        argument_unavailable_error("preadv2", "flags");
9760
        return -1;
9761
    }
9762
#endif
9763
9764
2
    if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
Line
Count
Source
106
2
#define PyBUF_WRITABLE 0x0001
  Branch (9764:9): [True: 0, False: 2]
9765
0
        return -1;
9766
0
    }
9767
2
#ifdef HAVE_PREADV2
9768
2
    do {
9769
2
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
2
#define Py_BEGIN_ALLOW_THREADS { \
143
2
                        PyThreadState *_save; \
144
2
                        _save = PyEval_SaveThread();
9770
2
        _Py_BEGIN_SUPPRESS_IPH
9771
2
        n = preadv2(fd, iov, cnt, offset, flags);
9772
2
        _Py_END_SUPPRESS_IPH
9773
2
        Py_END_ALLOW_THREADS
Line
Count
Source
147
2
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
2
                 }
9774
2
    } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (9774:14): [True: 0, False: 2]
  Branch (9774:23): [True: 0, False: 0]
  Branch (9774:41): [True: 0, False: 0]
9775
#else
9776
    do {
9777
#ifdef __APPLE__
9778
/* This entire function will be removed from the module dict when the API
9779
 * is not available.
9780
 */
9781
#pragma clang diagnostic push
9782
#pragma clang diagnostic ignored "-Wunguarded-availability"
9783
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
9784
#endif
9785
        Py_BEGIN_ALLOW_THREADS
9786
        _Py_BEGIN_SUPPRESS_IPH
9787
        n = preadv(fd, iov, cnt, offset);
9788
        _Py_END_SUPPRESS_IPH
9789
        Py_END_ALLOW_THREADS
9790
    } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9791
9792
#ifdef __APPLE__
9793
#pragma clang diagnostic pop
9794
#endif
9795
9796
#endif
9797
9798
2
    iov_cleanup(iov, buf, cnt);
9799
2
    if (n < 0) {
  Branch (9799:9): [True: 0, False: 2]
9800
0
        if (!async_err) {
  Branch (9800:13): [True: 0, False: 0]
9801
0
            posix_error();
9802
0
        }
9803
0
        return -1;
9804
0
    }
9805
9806
2
    return n;
9807
2
}
9808
#endif /* HAVE_PREADV */
9809
9810
9811
/*[clinic input]
9812
os.write -> Py_ssize_t
9813
9814
    fd: int
9815
    data: Py_buffer
9816
    /
9817
9818
Write a bytes object to a file descriptor.
9819
[clinic start generated code]*/
9820
9821
static Py_ssize_t
9822
os_write_impl(PyObject *module, int fd, Py_buffer *data)
9823
/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
9824
38.5k
{
9825
38.5k
    return _Py_write(fd, data->buf, data->len);
9826
38.5k
}
9827
9828
#ifdef HAVE_SENDFILE
9829
#ifdef __APPLE__
9830
/*[clinic input]
9831
os.sendfile
9832
9833
    out_fd: int
9834
    in_fd: int
9835
    offset: Py_off_t
9836
    count as sbytes: Py_off_t
9837
    headers: object(c_default="NULL") = ()
9838
    trailers: object(c_default="NULL") = ()
9839
    flags: int = 0
9840
9841
Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9842
[clinic start generated code]*/
9843
9844
static PyObject *
9845
os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9846
                 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9847
                 int flags)
9848
/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9849
#elif defined(__FreeBSD__) || defined(__DragonFly__)
9850
/*[clinic input]
9851
os.sendfile
9852
9853
    out_fd: int
9854
    in_fd: int
9855
    offset: Py_off_t
9856
    count: Py_ssize_t
9857
    headers: object(c_default="NULL") = ()
9858
    trailers: object(c_default="NULL") = ()
9859
    flags: int = 0
9860
9861
Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9862
[clinic start generated code]*/
9863
9864
static PyObject *
9865
os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9866
                 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9867
                 int flags)
9868
/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9869
#else
9870
/*[clinic input]
9871
os.sendfile
9872
9873
    out_fd: int
9874
    in_fd: int
9875
    offset as offobj: object
9876
    count: Py_ssize_t
9877
9878
Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9879
[clinic start generated code]*/
9880
9881
static PyObject *
9882
os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9883
                 Py_ssize_t count)
9884
/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9885
#endif
9886
17.2k
{
9887
17.2k
    Py_ssize_t ret;
9888
17.2k
    int async_err = 0;
9889
9890
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9891
#ifndef __APPLE__
9892
    off_t sbytes;
9893
#endif
9894
    Py_buffer *hbuf, *tbuf;
9895
    struct sf_hdtr sf;
9896
9897
    sf.headers = NULL;
9898
    sf.trailers = NULL;
9899
9900
    if (headers != NULL) {
9901
        if (!PySequence_Check(headers)) {
9902
            PyErr_SetString(PyExc_TypeError,
9903
                "sendfile() headers must be a sequence");
9904
            return NULL;
9905
        } else {
9906
            Py_ssize_t i = PySequence_Size(headers);
9907
            if (i < 0)
9908
                return NULL;
9909
            if (i > INT_MAX) {
9910
                PyErr_SetString(PyExc_OverflowError,
9911
                    "sendfile() header is too large");
9912
                return NULL;
9913
            }
9914
            if (i > 0) {
9915
                sf.hdr_cnt = (int)i;
9916
                if (iov_setup(&(sf.headers), &hbuf,
9917
                              headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
9918
                    return NULL;
9919
#ifdef __APPLE__
9920
                for (i = 0; i < sf.hdr_cnt; i++) {
9921
                    Py_ssize_t blen = sf.headers[i].iov_len;
9922
# define OFF_T_MAX 0x7fffffffffffffff
9923
                    if (sbytes >= OFF_T_MAX - blen) {
9924
                        PyErr_SetString(PyExc_OverflowError,
9925
                            "sendfile() header is too large");
9926
                        return NULL;
9927
                    }
9928
                    sbytes += blen;
9929
                }
9930
#endif
9931
            }
9932
        }
9933
    }
9934
    if (trailers != NULL) {
9935
        if (!PySequence_Check(trailers)) {
9936
            PyErr_SetString(PyExc_TypeError,
9937
                "sendfile() trailers must be a sequence");
9938
            return NULL;
9939
        } else {
9940
            Py_ssize_t i = PySequence_Size(trailers);
9941
            if (i < 0)
9942
                return NULL;
9943
            if (i > INT_MAX) {
9944
                PyErr_SetString(PyExc_OverflowError,
9945
                    "sendfile() trailer is too large");
9946
                return NULL;
9947
            }
9948
            if (i > 0) {
9949
                sf.trl_cnt = (int)i;
9950
                if (iov_setup(&(sf.trailers), &tbuf,
9951
                              trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
9952
                    return NULL;
9953
            }
9954
        }
9955
    }
9956
9957
    _Py_BEGIN_SUPPRESS_IPH
9958
    do {
9959
        Py_BEGIN_ALLOW_THREADS
9960
#ifdef __APPLE__
9961
        ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
9962
#else
9963
        ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
9964
#endif
9965
        Py_END_ALLOW_THREADS
9966
    } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9967
    _Py_END_SUPPRESS_IPH
9968
9969
    if (sf.headers != NULL)
9970
        iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9971
    if (sf.trailers != NULL)
9972
        iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9973
9974
    if (ret < 0) {
9975
        if ((errno == EAGAIN) || (errno == EBUSY)) {
9976
            if (sbytes != 0) {
9977
                // some data has been sent
9978
                goto done;
9979
            }
9980
            else {
9981
                // no data has been sent; upper application is supposed
9982
                // to retry on EAGAIN or EBUSY
9983
                return posix_error();
9984
            }
9985
        }
9986
        return (!async_err) ? posix_error() : NULL;
9987
    }
9988
    goto done;
9989
9990
done:
9991
    #if !defined(HAVE_LARGEFILE_SUPPORT)
9992
        return Py_BuildValue("l", sbytes);
9993
    #else
9994
        return Py_BuildValue("L", sbytes);
9995
    #endif
9996
9997
#else
9998
17.2k
#ifdef __linux__
9999
17.2k
    if (offobj == Py_None) {
Line
Count
Source
654
17.2k
#define Py_None (&_Py_NoneStruct)
  Branch (9999:9): [True: 0, False: 17.2k]
10000
0
        do {
10001
0
            Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
0
#define Py_BEGIN_ALLOW_THREADS { \
143
0
                        PyThreadState *_save; \
144
0
                        _save = PyEval_SaveThread();
10002
0
            ret = sendfile(out_fd, in_fd, NULL, count);
10003
0
            Py_END_ALLOW_THREADS
Line
Count
Source
147
0
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
0
                 }
10004
0
        } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (10004:18): [True: 0, False: 0]
  Branch (10004:29): [True: 0, False: 0]
  Branch (10004:47): [True: 0, False: 0]
10005
0
        if (ret < 0)
  Branch (10005:13): [True: 0, False: 0]
10006
0
            return (!async_err) ? posix_error() : NULL;
  Branch (10006:20): [True: 0, False: 0]
10007
0
        return Py_BuildValue("n", ret);
Line
Count
Source
20
0
#define Py_BuildValue                   _Py_BuildValue_SizeT
10008
0
    }
10009
17.2k
#endif
10010
17.2k
    off_t offset;
10011
17.2k
    if (!Py_off_t_converter(offobj, &offset))
  Branch (10011:9): [True: 0, False: 17.2k]
10012
0
        return NULL;
10013
10014
#if defined(__sun) && defined(__SVR4)
10015
    // On Solaris, sendfile raises EINVAL rather than returning 0
10016
    // when the offset is equal or bigger than the in_fd size.
10017
    struct stat st;
10018
10019
    do {
10020
        Py_BEGIN_ALLOW_THREADS
10021
        ret = fstat(in_fd, &st);
10022
        Py_END_ALLOW_THREADS
10023
    } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10024
    if (ret < 0)
10025
        return (!async_err) ? posix_error() : NULL;
10026
10027
    if (offset >= st.st_size) {
10028
        return Py_BuildValue("i", 0);
10029
    }
10030
10031
    // On illumos specifically sendfile() may perform a partial write but
10032
    // return -1/an error (in one confirmed case the destination socket
10033
    // had a 5 second timeout set and errno was EAGAIN) and it's on the client
10034
    // code to check if the offset parameter was modified by sendfile().
10035
    //
10036
    // We need this variable to track said change.
10037
    off_t original_offset = offset;
10038
#endif
10039
10040
17.2k
    do {
10041
17.2k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
17.2k
#define Py_BEGIN_ALLOW_THREADS { \
143
17.2k
                        PyThreadState *_save; \
144
17.2k
                        _save = PyEval_SaveThread();
10042
17.2k
        ret = sendfile(out_fd, in_fd, &offset, count);
10043
#if defined(__sun) && defined(__SVR4)
10044
        // This handles illumos-specific sendfile() partial write behavior,
10045
        // see a comment above for more details.
10046
        if (ret < 0 && offset != original_offset) {
10047
            ret = offset - original_offset;
10048
        }
10049
#endif
10050
17.2k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
17.2k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
17.2k
                 }
10051
17.2k
    } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (10051:14): [True: 6, False: 17.2k]
  Branch (10051:25): [True: 0, False: 6]
  Branch (10051:43): [True: 0, False: 0]
10052
17.2k
    if (ret < 0)
  Branch (10052:9): [True: 6, False: 17.2k]
10053
6
        return (!async_err) ? posix_error() : NULL;
  Branch (10053:16): [True: 6, False: 0]
10054
17.2k
    return Py_BuildValue("n", ret);
Line
Count
Source
20
17.2k
#define Py_BuildValue                   _Py_BuildValue_SizeT
10055
17.2k
#endif
10056
17.2k
}
10057
#endif /* HAVE_SENDFILE */
10058
10059
10060
#if defined(__APPLE__)
10061
/*[clinic input]
10062
os._fcopyfile
10063
10064
    in_fd: int
10065
    out_fd: int
10066
    flags: int
10067
    /
10068
10069
Efficiently copy content or metadata of 2 regular file descriptors (macOS).
10070
[clinic start generated code]*/
10071
10072
static PyObject *
10073
os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
10074
/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
10075
{
10076
    int ret;
10077
10078
    Py_BEGIN_ALLOW_THREADS
10079
    ret = fcopyfile(in_fd, out_fd, NULL, flags);
10080
    Py_END_ALLOW_THREADS
10081
    if (ret < 0)
10082
        return posix_error();
10083
    Py_RETURN_NONE;
10084
}
10085
#endif
10086
10087
10088
/*[clinic input]
10089
os.fstat
10090
10091
    fd : int
10092
10093
Perform a stat system call on the given file descriptor.
10094
10095
Like stat(), but for an open file descriptor.
10096
Equivalent to os.stat(fd).
10097
[clinic start generated code]*/
10098
10099
static PyObject *
10100
os_fstat_impl(PyObject *module, int fd)
10101
/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
10102
26.4k
{
10103
26.4k
    STRUCT_STAT st;
Line
Count
Source
473
26.4k
#  define STRUCT_STAT struct stat
10104
26.4k
    int res;
10105
26.4k
    int async_err = 0;
10106
10107
26.4k
    do {
10108
26.4k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
26.4k
#define Py_BEGIN_ALLOW_THREADS { \
143
26.4k
                        PyThreadState *_save; \
144
26.4k
                        _save = PyEval_SaveThread();
10109
26.4k
        res = FSTAT(fd, &st);
Line
Count
Source
472
26.4k
#  define FSTAT fstat
10110
26.4k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
26.4k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
26.4k
                 }
10111
26.4k
    } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (10111:14): [True: 8, False: 26.4k]
  Branch (10111:26): [True: 0, False: 8]
  Branch (10111:44): [True: 0, False: 0]
10112
26.4k
    if (res != 0) {
  Branch (10112:9): [True: 8, False: 26.4k]
10113
#ifdef MS_WINDOWS
10114
        return PyErr_SetFromWindowsErr(0);
10115
#else
10116
8
        return (!async_err) ? posix_error() : NULL;
  Branch (10116:16): [True: 8, False: 0]
10117
8
#endif
10118
8
    }
10119
10120
26.4k
    return _pystat_fromstructstat(module, &st);
10121
26.4k
}
10122
10123
10124
/*[clinic input]
10125
os.isatty -> bool
10126
    fd: int
10127
    /
10128
10129
Return True if the fd is connected to a terminal.
10130
10131
Return True if the file descriptor is an open file descriptor
10132
connected to the slave end of a terminal.
10133
[clinic start generated code]*/
10134
10135
static int
10136
os_isatty_impl(PyObject *module, int fd)
10137
/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
10138
3.58k
{
10139
3.58k
    int return_value;
10140
3.58k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
3.58k
#define Py_BEGIN_ALLOW_THREADS { \
143
3.58k
                        PyThreadState *_save; \
144
3.58k
                        _save = PyEval_SaveThread();
10141
3.58k
    _Py_BEGIN_SUPPRESS_IPH
10142
3.58k
    return_value = isatty(fd);
10143
3.58k
    _Py_END_SUPPRESS_IPH
10144
3.58k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
3.58k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
3.58k
                 }
10145
3.58k
    return return_value;
10146
3.58k
}
10147
10148
10149
#ifdef HAVE_PIPE
10150
/*[clinic input]
10151
os.pipe
10152
10153
Create a pipe.
10154
10155
Returns a tuple of two file descriptors:
10156
  (read_fd, write_fd)
10157
[clinic start generated code]*/
10158
10159
static PyObject *
10160
os_pipe_impl(PyObject *module)
10161
/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
10162
18.9k
{
10163
18.9k
    int fds[2];
10164
#ifdef MS_WINDOWS
10165
    HANDLE read, write;
10166
    SECURITY_ATTRIBUTES attr;
10167
    BOOL ok;
10168
#else
10169
18.9k
    int res;
10170
18.9k
#endif
10171
10172
#ifdef MS_WINDOWS
10173
    attr.nLength = sizeof(attr);
10174
    attr.lpSecurityDescriptor = NULL;
10175
    attr.bInheritHandle = FALSE;
10176
10177
    Py_BEGIN_ALLOW_THREADS
10178
    ok = CreatePipe(&read, &write, &attr, 0);
10179
    if (ok) {
10180
        fds[0] = _Py_open_osfhandle_noraise(read, _O_RDONLY);
10181
        fds[1] = _Py_open_osfhandle_noraise(write, _O_WRONLY);
10182
        if (fds[0] == -1 || fds[1] == -1) {
10183
            CloseHandle(read);
10184
            CloseHandle(write);
10185
            ok = 0;
10186
        }
10187
    }
10188
    Py_END_ALLOW_THREADS
10189
10190
    if (!ok)
10191
        return PyErr_SetFromWindowsErr(0);
10192
#else
10193
10194
18.9k
#ifdef HAVE_PIPE2
10195
18.9k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
18.9k
#define Py_BEGIN_ALLOW_THREADS { \
143
18.9k
                        PyThreadState *_save; \
144
18.9k
                        _save = PyEval_SaveThread();
10196
18.9k
    res = pipe2(fds, O_CLOEXEC);
10197
18.9k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
18.9k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
18.9k
                 }
10198
10199
18.9k
    if (res != 0 && errno == ENOSYS)
  Branch (10199:9): [True: 0, False: 18.9k]
  Branch (10199:21): [True: 0, False: 0]
10200
0
    {
10201
0
#endif
10202
0
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
0
#define Py_BEGIN_ALLOW_THREADS { \
143
0
                        PyThreadState *_save; \
144
0
                        _save = PyEval_SaveThread();
10203
0
        res = pipe(fds);
10204
0
        Py_END_ALLOW_THREADS
Line
Count
Source
147
0
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
0
                 }
10205
10206
0
        if (res == 0) {
  Branch (10206:13): [True: 0, False: 0]
10207
0
            if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
  Branch (10207:17): [True: 0, False: 0]
10208
0
                close(fds[0]);
10209
0
                close(fds[1]);
10210
0
                return NULL;
10211
0
            }
10212
0
            if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
  Branch (10212:17): [True: 0, False: 0]
10213
0
                close(fds[0]);
10214
0
                close(fds[1]);
10215
0
                return NULL;
10216
0
            }
10217
0
        }
10218
0
#ifdef HAVE_PIPE2
10219
0
    }
10220
18.9k
#endif
10221
10222
18.9k
    if (res != 0)
  Branch (10222:9): [True: 0, False: 18.9k]
10223
0
        return PyErr_SetFromErrno(PyExc_OSError);
10224
18.9k
#endif /* !MS_WINDOWS */
10225
18.9k
    return Py_BuildValue("(ii)", fds[0], fds[1]);
Line
Count
Source
20
18.9k
#define Py_BuildValue                   _Py_BuildValue_SizeT
10226
18.9k
}
10227
#endif  /* HAVE_PIPE */
10228
10229
10230
#ifdef HAVE_PIPE2
10231
/*[clinic input]
10232
os.pipe2
10233
10234
    flags: int
10235
    /
10236
10237
Create a pipe with flags set atomically.
10238
10239
Returns a tuple of two file descriptors:
10240
  (read_fd, write_fd)
10241
10242
flags can be constructed by ORing together one or more of these values:
10243
O_NONBLOCK, O_CLOEXEC.
10244
[clinic start generated code]*/
10245
10246
static PyObject *
10247
os_pipe2_impl(PyObject *module, int flags)
10248
/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
10249
2
{
10250
2
    int fds[2];
10251
2
    int res;
10252
10253
2
    res = pipe2(fds, flags);
10254
2
    if (res != 0)
  Branch (10254:9): [True: 0, False: 2]
10255
0
        return posix_error();
10256
2
    return Py_BuildValue("(ii)", fds[0], fds[1]);
Line
Count
Source
20
2
#define Py_BuildValue                   _Py_BuildValue_SizeT
10257
2
}
10258
#endif /* HAVE_PIPE2 */
10259
10260
10261
#ifdef HAVE_WRITEV
10262
/*[clinic input]
10263
os.writev -> Py_ssize_t
10264
    fd: int
10265
    buffers: object
10266
    /
10267
10268
Iterate over buffers, and write the contents of each to a file descriptor.
10269
10270
Returns the total number of bytes written.
10271
buffers must be a sequence of bytes-like objects.
10272
[clinic start generated code]*/
10273
10274
static Py_ssize_t
10275
os_writev_impl(PyObject *module, int fd, PyObject *buffers)
10276
/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
10277
3
{
10278
3
    Py_ssize_t cnt;
10279
3
    Py_ssize_t result;
10280
3
    int async_err = 0;
10281
3
    struct iovec *iov;
10282
3
    Py_buffer *buf;
10283
10284
3
    if (!PySequence_Check(buffers)) {
  Branch (10284:9): [True: 0, False: 3]
10285
0
        PyErr_SetString(PyExc_TypeError,
10286
0
            "writev() arg 2 must be a sequence");
10287
0
        return -1;
10288
0
    }
10289
3
    cnt = PySequence_Size(buffers);
10290
3
    if (cnt < 0)
  Branch (10290:9): [True: 0, False: 3]
10291
0
        return -1;
10292
10293
3
    if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
Line
Count
Source
105
3
#define PyBUF_SIMPLE 0
  Branch (10293:9): [True: 0, False: 3]
10294
0
        return -1;
10295
0
    }
10296
10297
3
    do {
10298
3
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
3
#define Py_BEGIN_ALLOW_THREADS { \
143
3
                        PyThreadState *_save; \
144
3
                        _save = PyEval_SaveThread();
10299
3
        result = writev(fd, iov, cnt);
10300
3
        Py_END_ALLOW_THREADS
Line
Count
Source
147
3
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
3
                 }
10301
3
    } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (10301:14): [True: 1, False: 2]
  Branch (10301:28): [True: 0, False: 1]
  Branch (10301:46): [True: 0, False: 0]
10302
10303
3
    iov_cleanup(iov, buf, cnt);
10304
3
    if (result < 0 && !async_err)
  Branch (10304:9): [True: 1, False: 2]
  Branch (10304:23): [True: 1, False: 0]
10305
1
        posix_error();
10306
10307
3
    return result;
10308
3
}
10309
#endif /* HAVE_WRITEV */
10310
10311
10312
#ifdef HAVE_PWRITE
10313
/*[clinic input]
10314
os.pwrite -> Py_ssize_t
10315
10316
    fd: int
10317
    buffer: Py_buffer
10318
    offset: Py_off_t
10319
    /
10320
10321
Write bytes to a file descriptor starting at a particular offset.
10322
10323
Write buffer to fd, starting at offset bytes from the beginning of
10324
the file.  Returns the number of bytes writte.  Does not change the
10325
current file offset.
10326
[clinic start generated code]*/
10327
10328
static Py_ssize_t
10329
os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
10330
/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
10331
1
{
10332
1
    Py_ssize_t size;
10333
1
    int async_err = 0;
10334
10335
1
    do {
10336
1
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
1
#define Py_BEGIN_ALLOW_THREADS { \
143
1
                        PyThreadState *_save; \
144
1
                        _save = PyEval_SaveThread();
10337
1
        _Py_BEGIN_SUPPRESS_IPH
10338
1
        size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
10339
1
        _Py_END_SUPPRESS_IPH
10340
1
        Py_END_ALLOW_THREADS
Line
Count
Source
147
1
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
1
                 }
10341
1
    } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (10341:14): [True: 0, False: 1]
  Branch (10341:26): [True: 0, False: 0]
  Branch (10341:44): [True: 0, False: 0]
10342
10343
1
    if (size < 0 && !async_err)
  Branch (10343:9): [True: 0, False: 1]
  Branch (10343:21): [True: 0, False: 0]
10344
0
        posix_error();
10345
1
    return size;
10346
1
}
10347
#endif /* HAVE_PWRITE */
10348
10349
#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
10350
/*[clinic input]
10351
os.pwritev -> Py_ssize_t
10352
10353
    fd: int
10354
    buffers: object
10355
    offset: Py_off_t
10356
    flags: int = 0
10357
    /
10358
10359
Writes the contents of bytes-like objects to a file descriptor at a given offset.
10360
10361
Combines the functionality of writev() and pwrite(). All buffers must be a sequence
10362
of bytes-like objects. Buffers are processed in array order. Entire contents of first
10363
buffer is written before proceeding to second, and so on. The operating system may
10364
set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
10365
This function writes the contents of each object to the file descriptor and returns
10366
the total number of bytes written.
10367
10368
The flags argument contains a bitwise OR of zero or more of the following flags:
10369
10370
- RWF_DSYNC
10371
- RWF_SYNC
10372
- RWF_APPEND
10373
10374
Using non-zero flags requires Linux 4.7 or newer.
10375
[clinic start generated code]*/
10376
10377
static Py_ssize_t
10378
os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
10379
                int flags)
10380
/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/
10381
1
{
10382
1
    Py_ssize_t cnt;
10383
1
    Py_ssize_t result;
10384
1
    int async_err = 0;
10385
1
    struct iovec *iov;
10386
1
    Py_buffer *buf;
10387
10388
1
    if (!PySequence_Check(buffers)) {
  Branch (10388:9): [True: 0, False: 1]
10389
0
        PyErr_SetString(PyExc_TypeError,
10390
0
            "pwritev() arg 2 must be a sequence");
10391
0
        return -1;
10392
0
    }
10393
10394
1
    cnt = PySequence_Size(buffers);
10395
1
    if (cnt < 0) {
  Branch (10395:9): [True: 0, False: 1]
10396
0
        return -1;
10397
0
    }
10398
10399
#ifndef HAVE_PWRITEV2
10400
    if(flags != 0) {
10401
        argument_unavailable_error("pwritev2", "flags");
10402
        return -1;
10403
    }
10404
#endif
10405
10406
1
    if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
Line
Count
Source
105
1
#define PyBUF_SIMPLE 0
  Branch (10406:9): [True: 0, False: 1]
10407
0
        return -1;
10408
0
    }
10409
1
#ifdef HAVE_PWRITEV2
10410
1
    do {
10411
1
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
1
#define Py_BEGIN_ALLOW_THREADS { \
143
1
                        PyThreadState *_save; \
144
1
                        _save = PyEval_SaveThread();
10412
1
        _Py_BEGIN_SUPPRESS_IPH
10413
1
        result = pwritev2(fd, iov, cnt, offset, flags);
10414
1
        _Py_END_SUPPRESS_IPH
10415
1
        Py_END_ALLOW_THREADS
Line
Count
Source
147
1
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
1
                 }
10416
1
    } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (10416:14): [True: 0, False: 1]
  Branch (10416:28): [True: 0, False: 0]
  Branch (10416:46): [True: 0, False: 0]
10417
#else
10418
10419
#ifdef __APPLE__
10420
/* This entire function will be removed from the module dict when the API
10421
 * is not available.
10422
 */
10423
#pragma clang diagnostic push
10424
#pragma clang diagnostic ignored "-Wunguarded-availability"
10425
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
10426
#endif
10427
    do {
10428
        Py_BEGIN_ALLOW_THREADS
10429
        _Py_BEGIN_SUPPRESS_IPH
10430
        result = pwritev(fd, iov, cnt, offset);
10431
        _Py_END_SUPPRESS_IPH
10432
        Py_END_ALLOW_THREADS
10433
    } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10434
10435
#ifdef __APPLE__
10436
#pragma clang diagnostic pop
10437
#endif
10438
10439
#endif
10440
10441
1
    iov_cleanup(iov, buf, cnt);
10442
1
    if (result < 0) {
  Branch (10442:9): [True: 0, False: 1]
10443
0
        if (!async_err) {
  Branch (10443:13): [True: 0, False: 0]
10444
0
            posix_error();
10445
0
        }
10446
0
        return -1;
10447
0
    }
10448
10449
1
    return result;
10450
1
}
10451
#endif /* HAVE_PWRITEV */
10452
10453
#ifdef HAVE_COPY_FILE_RANGE
10454
/*[clinic input]
10455
10456
os.copy_file_range
10457
    src: int
10458
        Source file descriptor.
10459
    dst: int
10460
        Destination file descriptor.
10461
    count: Py_ssize_t
10462
        Number of bytes to copy.
10463
    offset_src: object = None
10464
        Starting offset in src.
10465
    offset_dst: object = None
10466
        Starting offset in dst.
10467
10468
Copy count bytes from one file descriptor to another.
10469
10470
If offset_src is None, then src is read from the current position;
10471
respectively for offset_dst.
10472
[clinic start generated code]*/
10473
10474
static PyObject *
10475
os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10476
                        PyObject *offset_src, PyObject *offset_dst)
10477
/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
10478
3
{
10479
3
    off_t offset_src_val, offset_dst_val;
10480
3
    off_t *p_offset_src = NULL;
10481
3
    off_t *p_offset_dst = NULL;
10482
3
    Py_ssize_t ret;
10483
3
    int async_err = 0;
10484
    /* The flags argument is provided to allow
10485
     * for future extensions and currently must be to 0. */
10486
3
    int flags = 0;
10487
10488
10489
3
    if (count < 0) {
  Branch (10489:9): [True: 1, False: 2]
10490
1
        PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10491
1
        return NULL;
10492
1
    }
10493
10494
2
    if (offset_src != Py_None) {
Line
Count
Source
654
2
#define Py_None (&_Py_NoneStruct)
  Branch (10494:9): [True: 1, False: 1]
10495
1
        if (!Py_off_t_converter(offset_src, &offset_src_val)) {
  Branch (10495:13): [True: 0, False: 1]
10496
0
            return NULL;
10497
0
        }
10498
1
        p_offset_src = &offset_src_val;
10499
1
    }
10500
10501
2
    if (offset_dst != Py_None) {
Line
Count
Source
654
2
#define Py_None (&_Py_NoneStruct)
  Branch (10501:9): [True: 1, False: 1]
10502
1
        if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
  Branch (10502:13): [True: 0, False: 1]
10503
0
            return NULL;
10504
0
        }
10505
1
        p_offset_dst = &offset_dst_val;
10506
1
    }
10507
10508
2
    do {
10509
2
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
2
#define Py_BEGIN_ALLOW_THREADS { \
143
2
                        PyThreadState *_save; \
144
2
                        _save = PyEval_SaveThread();
10510
2
        ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
10511
2
        Py_END_ALLOW_THREADS
Line
Count
Source
147
2
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
2
                 }
10512
2
    } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (10512:14): [True: 0, False: 2]
  Branch (10512:25): [True: 0, False: 0]
  Branch (10512:43): [True: 0, False: 0]
10513
10514
2
    if (ret < 0) {
  Branch (10514:9): [True: 0, False: 2]
10515
0
        return (!async_err) ? posix_error() : NULL;
  Branch (10515:16): [True: 0, False: 0]
10516
0
    }
10517
10518
2
    return PyLong_FromSsize_t(ret);
10519
2
}
10520
#endif /* HAVE_COPY_FILE_RANGE*/
10521
10522
#if (defined(HAVE_SPLICE) && !defined(_AIX))
10523
/*[clinic input]
10524
10525
os.splice
10526
    src: int
10527
        Source file descriptor.
10528
    dst: int
10529
        Destination file descriptor.
10530
    count: Py_ssize_t
10531
        Number of bytes to copy.
10532
    offset_src: object = None
10533
        Starting offset in src.
10534
    offset_dst: object = None
10535
        Starting offset in dst.
10536
    flags: unsigned_int = 0
10537
        Flags to modify the semantics of the call.
10538
10539
Transfer count bytes from one pipe to a descriptor or vice versa.
10540
10541
If offset_src is None, then src is read from the current position;
10542
respectively for offset_dst. The offset associated to the file
10543
descriptor that refers to a pipe must be None.
10544
[clinic start generated code]*/
10545
10546
static PyObject *
10547
os_splice_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10548
               PyObject *offset_src, PyObject *offset_dst,
10549
               unsigned int flags)
10550
/*[clinic end generated code: output=d0386f25a8519dc5 input=047527c66c6d2e0a]*/
10551
4
{
10552
4
    off_t offset_src_val, offset_dst_val;
10553
4
    off_t *p_offset_src = NULL;
10554
4
    off_t *p_offset_dst = NULL;
10555
4
    Py_ssize_t ret;
10556
4
    int async_err = 0;
10557
10558
4
    if (count < 0) {
  Branch (10558:9): [True: 1, False: 3]
10559
1
        PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10560
1
        return NULL;
10561
1
    }
10562
10563
3
    if (offset_src != Py_None) {
Line
Count
Source
654
3
#define Py_None (&_Py_NoneStruct)
  Branch (10563:9): [True: 1, False: 2]
10564
1
        if (!Py_off_t_converter(offset_src, &offset_src_val)) {
  Branch (10564:13): [True: 0, False: 1]
10565
0
            return NULL;
10566
0
        }
10567
1
        p_offset_src = &offset_src_val;
10568
1
    }
10569
10570
3
    if (offset_dst != Py_None) {
Line
Count
Source
654
3
#define Py_None (&_Py_NoneStruct)
  Branch (10570:9): [True: 1, False: 2]
10571
1
        if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
  Branch (10571:13): [True: 0, False: 1]
10572
0
            return NULL;
10573
0
        }
10574
1
        p_offset_dst = &offset_dst_val;
10575
1
    }
10576
10577
3
    do {
10578
3
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
3
#define Py_BEGIN_ALLOW_THREADS { \
143
3
                        PyThreadState *_save; \
144
3
                        _save = PyEval_SaveThread();
10579
3
        ret = splice(src, p_offset_src, dst, p_offset_dst, count, flags);
10580
3
        Py_END_ALLOW_THREADS
Line
Count
Source
147
3
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
3
                 }
10581
3
    } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (10581:14): [True: 0, False: 3]
  Branch (10581:25): [True: 0, False: 0]
  Branch (10581:43): [True: 0, False: 0]
10582
10583
3
    if (ret < 0) {
  Branch (10583:9): [True: 0, False: 3]
10584
0
        return (!async_err) ? posix_error() : NULL;
  Branch (10584:16): [True: 0, False: 0]
10585
0
    }
10586
10587
3
    return PyLong_FromSsize_t(ret);
10588
3
}
10589
#endif /* HAVE_SPLICE*/
10590
10591
#ifdef HAVE_MKFIFO
10592
/*[clinic input]
10593
os.mkfifo
10594
10595
    path: path_t
10596
    mode: int=0o666
10597
    *
10598
    dir_fd: dir_fd(requires='mkfifoat')=None
10599
10600
Create a "fifo" (a POSIX named pipe).
10601
10602
If dir_fd is not None, it should be a file descriptor open to a directory,
10603
  and path should be relative; path will then be relative to that directory.
10604
dir_fd may not be implemented on your platform.
10605
  If it is unavailable, using it will raise a NotImplementedError.
10606
[clinic start generated code]*/
10607
10608
static PyObject *
10609
os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
10610
/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
10611
8
{
10612
8
    int result;
10613
8
    int async_err = 0;
10614
10615
8
    do {
10616
8
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
8
#define Py_BEGIN_ALLOW_THREADS { \
143
8
                        PyThreadState *_save; \
144
8
                        _save = PyEval_SaveThread();
10617
8
#ifdef HAVE_MKFIFOAT
10618
8
        if (dir_fd != DEFAULT_DIR_FD)
Line
Count
Source
904
8
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (10618:13): [True: 1, False: 7]
10619
1
            result = mkfifoat(dir_fd, path->narrow, mode);
10620
7
        else
10621
7
#endif
10622
7
            result = mkfifo(path->narrow, mode);
10623
8
        Py_END_ALLOW_THREADS
Line
Count
Source
147
8
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
8
                 }
10624
8
    } while (result != 0 && errno == EINTR &&
  Branch (10624:14): [True: 0, False: 8]
  Branch (10624:29): [True: 0, False: 0]
10625
8
             !(async_err = PyErr_CheckSignals()));
  Branch (10625:14): [True: 0, False: 0]
10626
8
    if (result != 0)
  Branch (10626:9): [True: 0, False: 8]
10627
0
        return (!async_err) ? posix_error() : NULL;
  Branch (10627:16): [True: 0, False: 0]
10628
10629
8
    Py_RETURN_NONE;
Line
Count
Source
661
8
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
8
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
8
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8
#  define _Py_CAST(type, expr) ((type)(expr))
10630
8
}
10631
#endif /* HAVE_MKFIFO */
10632
10633
10634
#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10635
/*[clinic input]
10636
os.mknod
10637
10638
    path: path_t
10639
    mode: int=0o600
10640
    device: dev_t=0
10641
    *
10642
    dir_fd: dir_fd(requires='mknodat')=None
10643
10644
Create a node in the file system.
10645
10646
Create a node in the file system (file, device special file or named pipe)
10647
at path.  mode specifies both the permissions to use and the
10648
type of node to be created, being combined (bitwise OR) with one of
10649
S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO.  If S_IFCHR or S_IFBLK is set on mode,
10650
device defines the newly created device special file (probably using
10651
os.makedev()).  Otherwise device is ignored.
10652
10653
If dir_fd is not None, it should be a file descriptor open to a directory,
10654
  and path should be relative; path will then be relative to that directory.
10655
dir_fd may not be implemented on your platform.
10656
  If it is unavailable, using it will raise a NotImplementedError.
10657
[clinic start generated code]*/
10658
10659
static PyObject *
10660
os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
10661
              int dir_fd)
10662
/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
10663
3
{
10664
3
    int result;
10665
3
    int async_err = 0;
10666
10667
3
    do {
10668
3
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
3
#define Py_BEGIN_ALLOW_THREADS { \
143
3
                        PyThreadState *_save; \
144
3
                        _save = PyEval_SaveThread();
10669
3
#ifdef HAVE_MKNODAT
10670
3
        if (dir_fd != DEFAULT_DIR_FD)
Line
Count
Source
904
3
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (10670:13): [True: 1, False: 2]
10671
1
            result = mknodat(dir_fd, path->narrow, mode, device);
10672
2
        else
10673
2
#endif
10674
2
            result = mknod(path->narrow, mode, device);
10675
3
        Py_END_ALLOW_THREADS
Line
Count
Source
147
3
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
3
                 }
10676
3
    } while (result != 0 && errno == EINTR &&
  Branch (10676:14): [True: 0, False: 3]
  Branch (10676:29): [True: 0, False: 0]
10677
3
             !(async_err = PyErr_CheckSignals()));
  Branch (10677:14): [True: 0, False: 0]
10678
3
    if (result != 0)
  Branch (10678:9): [True: 0, False: 3]
10679
0
        return (!async_err) ? posix_error() : NULL;
  Branch (10679:16): [True: 0, False: 0]
10680
10681
3
    Py_RETURN_NONE;
Line
Count
Source
661
3
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
3
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
3
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
3
#  define _Py_CAST(type, expr) ((type)(expr))
10682
3
}
10683
#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10684
10685
10686
#ifdef HAVE_DEVICE_MACROS
10687
/*[clinic input]
10688
os.major -> unsigned_int
10689
10690
    device: dev_t
10691
    /
10692
10693
Extracts a device major number from a raw device number.
10694
[clinic start generated code]*/
10695
10696
static unsigned int
10697
os_major_impl(PyObject *module, dev_t device)
10698
/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
10699
2
{
10700
2
    return major(device);
10701
2
}
10702
10703
10704
/*[clinic input]
10705
os.minor -> unsigned_int
10706
10707
    device: dev_t
10708
    /
10709
10710
Extracts a device minor number from a raw device number.
10711
[clinic start generated code]*/
10712
10713
static unsigned int
10714
os_minor_impl(PyObject *module, dev_t device)
10715
/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
10716
2
{
10717
2
    return minor(device);
10718
2
}
10719
10720
10721
/*[clinic input]
10722
os.makedev -> dev_t
10723
10724
    major: int
10725
    minor: int
10726
    /
10727
10728
Composes a raw device number from the major and minor device numbers.
10729
[clinic start generated code]*/
10730
10731
static dev_t
10732
os_makedev_impl(PyObject *module, int major, int minor)
10733
/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
10734
1
{
10735
1
    return makedev(major, minor);
10736
1
}
10737
#endif /* HAVE_DEVICE_MACROS */
10738
10739
10740
#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
10741
/*[clinic input]
10742
os.ftruncate
10743
10744
    fd: int
10745
    length: Py_off_t
10746
    /
10747
10748
Truncate a file, specified by file descriptor, to a specific length.
10749
[clinic start generated code]*/
10750
10751
static PyObject *
10752
os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10753
/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
10754
263
{
10755
263
    int result;
10756
263
    int async_err = 0;
10757
10758
263
    if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
  Branch (10758:9): [True: 0, False: 263]
10759
0
        return NULL;
10760
0
    }
10761
10762
263
    do {
10763
263
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
263
#define Py_BEGIN_ALLOW_THREADS { \
143
263
                        PyThreadState *_save; \
144
263
                        _save = PyEval_SaveThread();
10764
263
        _Py_BEGIN_SUPPRESS_IPH
10765
#ifdef MS_WINDOWS
10766
        result = _chsize_s(fd, length);
10767
#else
10768
263
        result = ftruncate(fd, length);
10769
263
#endif
10770
263
        _Py_END_SUPPRESS_IPH
10771
263
        Py_END_ALLOW_THREADS
Line
Count
Source
147
263
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
263
                 }
10772
263
    } while (result != 0 && errno == EINTR &&
  Branch (10772:14): [True: 4, False: 259]
  Branch (10772:29): [True: 0, False: 4]
10773
263
             !(async_err = PyErr_CheckSignals()));
  Branch (10773:14): [True: 0, False: 0]
10774
263
    if (result != 0)
  Branch (10774:9): [True: 4, False: 259]
10775
4
        return (!async_err) ? posix_error() : NULL;
  Branch (10775:16): [True: 4, False: 0]
10776
263
    Py_RETURN_NONE;
Line
Count
Source
661
259
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
259
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
259
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
259
#  define _Py_CAST(type, expr) ((type)(expr))
10777
263
}
10778
#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
10779
10780
10781
#if defined HAVE_TRUNCATE || defined MS_WINDOWS
10782
/*[clinic input]
10783
os.truncate
10784
    path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10785
    length: Py_off_t
10786
10787
Truncate a file, specified by path, to a specific length.
10788
10789
On some platforms, path may also be specified as an open file descriptor.
10790
  If this functionality is unavailable, using it raises an exception.
10791
[clinic start generated code]*/
10792
10793
static PyObject *
10794
os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10795
/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
10796
7
{
10797
7
    int result;
10798
#ifdef MS_WINDOWS
10799
    int fd;
10800
#endif
10801
10802
7
    if (path->fd != -1)
  Branch (10802:9): [True: 1, False: 6]
10803
1
        return os_ftruncate_impl(module, path->fd, length);
10804
10805
6
    if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
  Branch (10805:9): [True: 0, False: 6]
10806
0
        return NULL;
10807
0
    }
10808
10809
6
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
6
#define Py_BEGIN_ALLOW_THREADS { \
143
6
                        PyThreadState *_save; \
144
6
                        _save = PyEval_SaveThread();
10810
6
    _Py_BEGIN_SUPPRESS_IPH
10811
#ifdef MS_WINDOWS
10812
    fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
10813
    if (fd < 0)
10814
        result = -1;
10815
    else {
10816
        result = _chsize_s(fd, length);
10817
        close(fd);
10818
        if (result < 0)
10819
            errno = result;
10820
    }
10821
#else
10822
6
    result = truncate(path->narrow, length);
10823
6
#endif
10824
6
    _Py_END_SUPPRESS_IPH
10825
6
    Py_END_ALLOW_THREADS
Line
Count
Source
147
6
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
6
                 }
10826
6
    if (result < 0)
  Branch (10826:9): [True: 5, False: 1]
10827
5
        return posix_path_error(path);
10828
10829
6
    Py_RETURN_NONE;
Line
Count
Source
661
1
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
10830
6
}
10831
#endif /* HAVE_TRUNCATE || MS_WINDOWS */
10832
10833
10834
/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10835
   and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10836
   defined, which is the case in Python on AIX. AIX bug report:
10837
   http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10838
#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10839
#  define POSIX_FADVISE_AIX_BUG
10840
#endif
10841
10842
10843
#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
10844
/*[clinic input]
10845
os.posix_fallocate
10846
10847
    fd: int
10848
    offset: Py_off_t
10849
    length: Py_off_t
10850
    /
10851
10852
Ensure a file has allocated at least a particular number of bytes on disk.
10853
10854
Ensure that the file specified by fd encompasses a range of bytes
10855
starting at offset bytes from the beginning and continuing for length bytes.
10856
[clinic start generated code]*/
10857
10858
static PyObject *
10859
os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
10860
                        Py_off_t length)
10861
/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
10862
2
{
10863
2
    int result;
10864
2
    int async_err = 0;
10865
10866
2
    do {
10867
2
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
2
#define Py_BEGIN_ALLOW_THREADS { \
143
2
                        PyThreadState *_save; \
144
2
                        _save = PyEval_SaveThread();
10868
2
        result = posix_fallocate(fd, offset, length);
10869
2
        Py_END_ALLOW_THREADS
Line
Count
Source
147
2
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
2
                 }
10870
2
    } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (10870:14): [True: 0, False: 2]
  Branch (10870:33): [True: 0, False: 0]
10871
10872
2
    if (result == 0)
  Branch (10872:9): [True: 1, False: 1]
10873
1
        Py_RETURN_NONE;
Line
Count
Source
661
1
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
10874
10875
1
    if (async_err)
  Branch (10875:9): [True: 0, False: 1]
10876
0
        return NULL;
10877
10878
1
    errno = result;
10879
1
    return posix_error();
10880
1
}
10881
#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
10882
10883
10884
#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
10885
/*[clinic input]
10886
os.posix_fadvise
10887
10888
    fd: int
10889
    offset: Py_off_t
10890
    length: Py_off_t
10891
    advice: int
10892
    /
10893
10894
Announce an intention to access data in a specific pattern.
10895
10896
Announce an intention to access data in a specific pattern, thus allowing
10897
the kernel to make optimizations.
10898
The advice applies to the region of the file specified by fd starting at
10899
offset and continuing for length bytes.
10900
advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10901
POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10902
POSIX_FADV_DONTNEED.
10903
[clinic start generated code]*/
10904
10905
static PyObject *
10906
os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
10907
                      Py_off_t length, int advice)
10908
/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
10909
2
{
10910
2
    int result;
10911
2
    int async_err = 0;
10912
10913
2
    do {
10914
2
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
2
#define Py_BEGIN_ALLOW_THREADS { \
143
2
                        PyThreadState *_save; \
144
2
                        _save = PyEval_SaveThread();
10915
2
        result = posix_fadvise(fd, offset, length, advice);
10916
2
        Py_END_ALLOW_THREADS
Line
Count
Source
147
2
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
2
                 }
10917
2
    } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
  Branch (10917:14): [True: 0, False: 2]
  Branch (10917:33): [True: 0, False: 0]
10918
10919
2
    if (result == 0)
  Branch (10919:9): [True: 1, False: 1]
10920
1
        Py_RETURN_NONE;
Line
Count
Source
661
1
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
1
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
1
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1
#  define _Py_CAST(type, expr) ((type)(expr))
10921
10922
1
    if (async_err)
  Branch (10922:9): [True: 0, False: 1]
10923
0
        return NULL;
10924
10925
1
    errno = result;
10926
1
    return posix_error();
10927
1
}
10928
#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
10929
10930
10931
#ifdef MS_WINDOWS
10932
static PyObject*
10933
win32_putenv(PyObject *name, PyObject *value)
10934
{
10935
    /* Search from index 1 because on Windows starting '=' is allowed for
10936
       defining hidden environment variables. */
10937
    if (PyUnicode_GET_LENGTH(name) == 0 ||
10938
        PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10939
    {
10940
        PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10941
        return NULL;
10942
    }
10943
    PyObject *unicode;
10944
    if (value != NULL) {
10945
        unicode = PyUnicode_FromFormat("%U=%U", name, value);
10946
    }
10947
    else {
10948
        unicode = PyUnicode_FromFormat("%U=", name);
10949
    }
10950
    if (unicode == NULL) {
10951
        return NULL;
10952
    }
10953
10954
    Py_ssize_t size;
10955
    /* PyUnicode_AsWideCharString() rejects embedded null characters */
10956
    wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10957
    Py_DECREF(unicode);
10958
10959
    if (env == NULL) {
10960
        return NULL;
10961
    }
10962
    if (size > _MAX_ENV) {
10963
        PyErr_Format(PyExc_ValueError,
10964
                     "the environment variable is longer than %u characters",
10965
                     _MAX_ENV);
10966
        PyMem_Free(env);
10967
        return NULL;
10968
    }
10969
10970
    /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10971
       Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10972
       and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10973
10974
       Prefer _wputenv() to be compatible with C libraries using CRT
10975
       variables and CRT functions using these variables (ex: getenv()). */
10976
    int err = _wputenv(env);
10977
    PyMem_Free(env);
10978
10979
    if (err) {
10980
        posix_error();
10981
        return NULL;
10982
    }
10983
10984
    Py_RETURN_NONE;
10985
}
10986
#endif
10987
10988
10989
#ifdef MS_WINDOWS
10990
/*[clinic input]
10991
os.putenv
10992
10993
    name: unicode
10994
    value: unicode
10995
    /
10996
10997
Change or add an environment variable.
10998
[clinic start generated code]*/
10999
11000
static PyObject *
11001
os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
11002
/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
11003
{
11004
    if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
11005
        return NULL;
11006
    }
11007
    return win32_putenv(name, value);
11008
}
11009
#else
11010
/*[clinic input]
11011
os.putenv
11012
11013
    name: FSConverter
11014
    value: FSConverter
11015
    /
11016
11017
Change or add an environment variable.
11018
[clinic start generated code]*/
11019
11020
static PyObject *
11021
os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
11022
/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
11023
8.86k
{
11024
8.86k
    const char *name_string = PyBytes_AS_STRING(name);
Line
Count
Source
39
8.86k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
8.86k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8.86k
#  define _Py_CAST(type, expr) ((type)(expr))
11025
8.86k
    const char *value_string = PyBytes_AS_STRING(value);
Line
Count
Source
39
8.86k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
8.86k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8.86k
#  define _Py_CAST(type, expr) ((type)(expr))
11026
11027
8.86k
    if (strchr(name_string, '=') != NULL) {
  Branch (11027:9): [True: 5, False: 8.85k]
11028
5
        PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
11029
5
        return NULL;
11030
5
    }
11031
11032
8.85k
    if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
  Branch (11032:9): [True: 0, False: 8.85k]
11033
0
        return NULL;
11034
0
    }
11035
11036
8.85k
    if (setenv(name_string, value_string, 1)) {
  Branch (11036:9): [True: 1, False: 8.85k]
11037
1
        return posix_error();
11038
1
    }
11039
8.85k
    Py_RETURN_NONE;
Line
Count
Source
661
8.85k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
8.85k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
8.85k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8.85k
#  define _Py_CAST(type, expr) ((type)(expr))
11040
8.85k
}
11041
#endif  /* !defined(MS_WINDOWS) */
11042
11043
11044
#ifdef MS_WINDOWS
11045
/*[clinic input]
11046
os.unsetenv
11047
    name: unicode
11048
    /
11049
11050
Delete an environment variable.
11051
[clinic start generated code]*/
11052
11053
static PyObject *
11054
os_unsetenv_impl(PyObject *module, PyObject *name)
11055
/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
11056
{
11057
    if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
11058
        return NULL;
11059
    }
11060
    return win32_putenv(name, NULL);
11061
}
11062
#else
11063
/*[clinic input]
11064
os.unsetenv
11065
    name: FSConverter
11066
    /
11067
11068
Delete an environment variable.
11069
[clinic start generated code]*/
11070
11071
static PyObject *
11072
os_unsetenv_impl(PyObject *module, PyObject *name)
11073
/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
11074
8.47k
{
11075
8.47k
    if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
  Branch (11075:9): [True: 0, False: 8.47k]
11076
0
        return NULL;
11077
0
    }
11078
#ifdef HAVE_BROKEN_UNSETENV
11079
    unsetenv(PyBytes_AS_STRING(name));
11080
#else
11081
8.47k
    int err = unsetenv(PyBytes_AS_STRING(name));
Line
Count
Source
39
8.47k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
8.47k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8.47k
#  define _Py_CAST(type, expr) ((type)(expr))
11082
8.47k
    if (err) {
  Branch (11082:9): [True: 4, False: 8.47k]
11083
4
        return posix_error();
11084
4
    }
11085
8.47k
#endif
11086
11087
8.47k
    Py_RETURN_NONE;
Line
Count
Source
661
8.47k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
8.47k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
8.47k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8.47k
#  define _Py_CAST(type, expr) ((type)(expr))
11088
8.47k
}
11089
#endif /* !MS_WINDOWS */
11090
11091
11092
/*[clinic input]
11093
os.strerror
11094
11095
    code: int
11096
    /
11097
11098
Translate an error code to a message string.
11099
[clinic start generated code]*/
11100
11101
static PyObject *
11102
os_strerror_impl(PyObject *module, int code)
11103
/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
11104
2.09k
{
11105
2.09k
    char *message = strerror(code);
11106
2.09k
    if (message == NULL) {
  Branch (11106:9): [True: 0, False: 2.09k]
11107
0
        PyErr_SetString(PyExc_ValueError,
11108
0
                        "strerror() argument out of range");
11109
0
        return NULL;
11110
0
    }
11111
2.09k
    return PyUnicode_DecodeLocale(message, "surrogateescape");
11112
2.09k
}
11113
11114
11115
#ifdef HAVE_SYS_WAIT_H
11116
#ifdef WCOREDUMP
11117
/*[clinic input]
11118
os.WCOREDUMP -> bool
11119
11120
    status: int
11121
    /
11122
11123
Return True if the process returning status was dumped to a core file.
11124
[clinic start generated code]*/
11125
11126
static int
11127
os_WCOREDUMP_impl(PyObject *module, int status)
11128
/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
11129
0
{
11130
0
    WAIT_TYPE wait_status;
Line
Count
Source
450
0
#  define WAIT_TYPE int
11131
0
    WAIT_STATUS_INT(wait_status) = status;
Line
Count
Source
451
0
#  define WAIT_STATUS_INT(s) (s)
11132
0
    return WCOREDUMP(wait_status);
11133
0
}
11134
#endif /* WCOREDUMP */
11135
11136
11137
#ifdef WIFCONTINUED
11138
/*[clinic input]
11139
os.WIFCONTINUED -> bool
11140
11141
    status: int
11142
11143
Return True if a particular process was continued from a job control stop.
11144
11145
Return True if the process returning status was continued from a
11146
job control stop.
11147
[clinic start generated code]*/
11148
11149
static int
11150
os_WIFCONTINUED_impl(PyObject *module, int status)
11151
/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
11152
0
{
11153
0
    WAIT_TYPE wait_status;
Line
Count
Source
450
0
#  define WAIT_TYPE int
11154
0
    WAIT_STATUS_INT(wait_status) = status;
Line
Count
Source
451
0
#  define WAIT_STATUS_INT(s) (s)
11155
0
    return WIFCONTINUED(wait_status);
11156
0
}
11157
#endif /* WIFCONTINUED */
11158
11159
11160
#ifdef WIFSTOPPED
11161
/*[clinic input]
11162
os.WIFSTOPPED -> bool
11163
11164
    status: int
11165
11166
Return True if the process returning status was stopped.
11167
[clinic start generated code]*/
11168
11169
static int
11170
os_WIFSTOPPED_impl(PyObject *module, int status)
11171
/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
11172
4.17k
{
11173
4.17k
    WAIT_TYPE wait_status;
Line
Count
Source
450
4.17k
#  define WAIT_TYPE int
11174
4.17k
    WAIT_STATUS_INT(wait_status) = status;
Line
Count
Source
451
4.17k
#  define WAIT_STATUS_INT(s) (s)
11175
4.17k
    return WIFSTOPPED(wait_status);
11176
4.17k
}
11177
#endif /* WIFSTOPPED */
11178
11179
11180
#ifdef WIFSIGNALED
11181
/*[clinic input]
11182
os.WIFSIGNALED -> bool
11183
11184
    status: int
11185
11186
Return True if the process returning status was terminated by a signal.
11187
[clinic start generated code]*/
11188
11189
static int
11190
os_WIFSIGNALED_impl(PyObject *module, int status)
11191
/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
11192
0
{
11193
0
    WAIT_TYPE wait_status;
Line
Count
Source
450
0
#  define WAIT_TYPE int
11194
0
    WAIT_STATUS_INT(wait_status) = status;
Line
Count
Source
451
0
#  define WAIT_STATUS_INT(s) (s)
11195
0
    return WIFSIGNALED(wait_status);
11196
0
}
11197
#endif /* WIFSIGNALED */
11198
11199
11200
#ifdef WIFEXITED
11201
/*[clinic input]
11202
os.WIFEXITED -> bool
11203
11204
    status: int
11205
11206
Return True if the process returning status exited via the exit() system call.
11207
[clinic start generated code]*/
11208
11209
static int
11210
os_WIFEXITED_impl(PyObject *module, int status)
11211
/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
11212
0
{
11213
0
    WAIT_TYPE wait_status;
Line
Count
Source
450
0
#  define WAIT_TYPE int
11214
0
    WAIT_STATUS_INT(wait_status) = status;
Line
Count
Source
451
0
#  define WAIT_STATUS_INT(s) (s)
11215
0
    return WIFEXITED(wait_status);
11216
0
}
11217
#endif /* WIFEXITED */
11218
11219
11220
#ifdef WEXITSTATUS
11221
/*[clinic input]
11222
os.WEXITSTATUS -> int
11223
11224
    status: int
11225
11226
Return the process return code from status.
11227
[clinic start generated code]*/
11228
11229
static int
11230
os_WEXITSTATUS_impl(PyObject *module, int status)
11231
/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
11232
0
{
11233
0
    WAIT_TYPE wait_status;
Line
Count
Source
450
0
#  define WAIT_TYPE int
11234
0
    WAIT_STATUS_INT(wait_status) = status;
Line
Count
Source
451
0
#  define WAIT_STATUS_INT(s) (s)
11235
0
    return WEXITSTATUS(wait_status);
11236
0
}
11237
#endif /* WEXITSTATUS */
11238
11239
11240
#ifdef WTERMSIG
11241
/*[clinic input]
11242
os.WTERMSIG -> int
11243
11244
    status: int
11245
11246
Return the signal that terminated the process that provided the status value.
11247
[clinic start generated code]*/
11248
11249
static int
11250
os_WTERMSIG_impl(PyObject *module, int status)
11251
/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
11252
0
{
11253
0
    WAIT_TYPE wait_status;
Line
Count
Source
450
0
#  define WAIT_TYPE int
11254
0
    WAIT_STATUS_INT(wait_status) = status;
Line
Count
Source
451
0
#  define WAIT_STATUS_INT(s) (s)
11255
0
    return WTERMSIG(wait_status);
11256
0
}
11257
#endif /* WTERMSIG */
11258
11259
11260
#ifdef WSTOPSIG
11261
/*[clinic input]
11262
os.WSTOPSIG -> int
11263
11264
    status: int
11265
11266
Return the signal that stopped the process that provided the status value.
11267
[clinic start generated code]*/
11268
11269
static int
11270
os_WSTOPSIG_impl(PyObject *module, int status)
11271
/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
11272
1
{
11273
1
    WAIT_TYPE wait_status;
Line
Count
Source
450
1
#  define WAIT_TYPE int
11274
1
    WAIT_STATUS_INT(wait_status) = status;
Line
Count
Source
451
1
#  define WAIT_STATUS_INT(s) (s)
11275
1
    return WSTOPSIG(wait_status);
11276
1
}
11277
#endif /* WSTOPSIG */
11278
#endif /* HAVE_SYS_WAIT_H */
11279
11280
11281
#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
11282
#ifdef _SCO_DS
11283
/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
11284
   needed definitions in sys/statvfs.h */
11285
#define _SVID3
11286
#endif
11287
#include <sys/statvfs.h>
11288
11289
static PyObject*
11290
104
_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
11291
104
    PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
11292
104
    PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
11293
104
    if (v == NULL)
  Branch (11293:9): [True: 0, False: 104]
11294
0
        return NULL;
11295
11296
104
#if !defined(HAVE_LARGEFILE_SUPPORT)
11297
104
    PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11298
104
    PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11299
104
    PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11300
104
    PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11301
104
    PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11302
104
    PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11303
104
    PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11304
104
    PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11305
104
    PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11306
104
    PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11307
#else
11308
    PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11309
    PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11310
    PyStructSequence_SET_ITEM(v, 2,
11311
                              PyLong_FromLongLong((long long) st.f_blocks));
11312
    PyStructSequence_SET_ITEM(v, 3,
11313
                              PyLong_FromLongLong((long long) st.f_bfree));
11314
    PyStructSequence_SET_ITEM(v, 4,
11315
                              PyLong_FromLongLong((long long) st.f_bavail));
11316
    PyStructSequence_SET_ITEM(v, 5,
11317
                              PyLong_FromLongLong((long long) st.f_files));
11318
    PyStructSequence_SET_ITEM(v, 6,
11319
                              PyLong_FromLongLong((long long) st.f_ffree));
11320
    PyStructSequence_SET_ITEM(v, 7,
11321
                              PyLong_FromLongLong((long long) st.f_favail));
11322
    PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11323
    PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
11324
#endif
11325
/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
11326
 * (issue #32390). */
11327
#if defined(_AIX) && defined(_ALL_SOURCE)
11328
    PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
11329
#else
11330
104
    PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Line
Count
Source
38
104
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
104
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
104
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
104
#  define _Py_CAST(type, expr) ((type)(expr))
11331
104
#endif
11332
104
    if (PyErr_Occurred()) {
  Branch (11332:9): [True: 0, False: 104]
11333
0
        Py_DECREF(v);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
11334
0
        return NULL;
11335
0
    }
11336
11337
104
    return v;
11338
104
}
11339
11340
11341
/*[clinic input]
11342
os.fstatvfs
11343
    fd: int
11344
    /
11345
11346
Perform an fstatvfs system call on the given fd.
11347
11348
Equivalent to statvfs(fd).
11349
[clinic start generated code]*/
11350
11351
static PyObject *
11352
os_fstatvfs_impl(PyObject *module, int fd)
11353
/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
11354
2
{
11355
2
    int result;
11356
2
    int async_err = 0;
11357
2
    struct statvfs st;
11358
11359
2
    do {
11360
2
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
2
#define Py_BEGIN_ALLOW_THREADS { \
143
2
                        PyThreadState *_save; \
144
2
                        _save = PyEval_SaveThread();
11361
2
        result = fstatvfs(fd, &st);
11362
2
        Py_END_ALLOW_THREADS
Line
Count
Source
147
2
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
2
                 }
11363
2
    } while (result != 0 && errno == EINTR &&
  Branch (11363:14): [True: 1, False: 1]
  Branch (11363:29): [True: 0, False: 1]
11364
2
             !(async_err = PyErr_CheckSignals()));
  Branch (11364:14): [True: 0, False: 0]
11365
2
    if (result != 0)
  Branch (11365:9): [True: 1, False: 1]
11366
1
        return (!async_err) ? posix_error() : NULL;
  Branch (11366:16): [True: 1, False: 0]
11367
11368
1
    return _pystatvfs_fromstructstatvfs(module, st);
11369
2
}
11370
#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
11371
11372
11373
#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
11374
#include <sys/statvfs.h>
11375
/*[clinic input]
11376
os.statvfs
11377
11378
    path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
11379
11380
Perform a statvfs system call on the given path.
11381
11382
path may always be specified as a string.
11383
On some platforms, path may also be specified as an open file descriptor.
11384
  If this functionality is unavailable, using it raises an exception.
11385
[clinic start generated code]*/
11386
11387
static PyObject *
11388
os_statvfs_impl(PyObject *module, path_t *path)
11389
/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
11390
103
{
11391
103
    int result;
11392
103
    struct statvfs st;
11393
11394
103
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
103
#define Py_BEGIN_ALLOW_THREADS { \
143
103
                        PyThreadState *_save; \
144
103
                        _save = PyEval_SaveThread();
11395
103
#ifdef HAVE_FSTATVFS
11396
103
    if (path->fd != -1) {
  Branch (11396:9): [True: 1, False: 102]
11397
1
        result = fstatvfs(path->fd, &st);
11398
1
    }
11399
102
    else
11400
102
#endif
11401
102
        result = statvfs(path->narrow, &st);
11402
103
    Py_END_ALLOW_THREADS
Line
Count
Source
147
103
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
103
                 }
11403
11404
103
    if (result) {
  Branch (11404:9): [True: 0, False: 103]
11405
0
        return path_error(path);
11406
0
    }
11407
11408
103
    return _pystatvfs_fromstructstatvfs(module, st);
11409
103
}
11410
#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
11411
11412
11413
#ifdef MS_WINDOWS
11414
/*[clinic input]
11415
os._getdiskusage
11416
11417
    path: path_t
11418
11419
Return disk usage statistics about the given path as a (total, free) tuple.
11420
[clinic start generated code]*/
11421
11422
static PyObject *
11423
os__getdiskusage_impl(PyObject *module, path_t *path)
11424
/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
11425
{
11426
    BOOL retval;
11427
    ULARGE_INTEGER _, total, free;
11428
    DWORD err = 0;
11429
11430
    Py_BEGIN_ALLOW_THREADS
11431
    retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
11432
    Py_END_ALLOW_THREADS
11433
    if (retval == 0) {
11434
        if (GetLastError() == ERROR_DIRECTORY) {
11435
            wchar_t *dir_path = NULL;
11436
11437
            dir_path = PyMem_New(wchar_t, path->length + 1);
11438
            if (dir_path == NULL) {
11439
                return PyErr_NoMemory();
11440
            }
11441
11442
            wcscpy_s(dir_path, path->length + 1, path->wide);
11443
11444
            if (_dirnameW(dir_path) != -1) {
11445
                Py_BEGIN_ALLOW_THREADS
11446
                retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
11447
                Py_END_ALLOW_THREADS
11448
            }
11449
            /* Record the last error in case it's modified by PyMem_Free. */
11450
            err = GetLastError();
11451
            PyMem_Free(dir_path);
11452
            if (retval) {
11453
                goto success;
11454
            }
11455
        }
11456
        return PyErr_SetFromWindowsErr(err);
11457
    }
11458
11459
success:
11460
    return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
11461
}
11462
#endif /* MS_WINDOWS */
11463
11464
11465
/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
11466
 * It maps strings representing configuration variable names to
11467
 * integer values, allowing those functions to be called with the
11468
 * magic names instead of polluting the module's namespace with tons of
11469
 * rarely-used constants.  There are three separate tables that use
11470
 * these definitions.
11471
 *
11472
 * This code is always included, even if none of the interfaces that
11473
 * need it are included.  The #if hackery needed to avoid it would be
11474
 * sufficiently pervasive that it's not worth the loss of readability.
11475
 */
11476
struct constdef {
11477
    const char *name;
11478
    int value;
11479
};
11480
11481
static int
11482
conv_confname(PyObject *arg, int *valuep, struct constdef *table,
11483
              size_t tablesize)
11484
573
{
11485
573
    if (PyLong_Check(arg)) {
Line
Count
Source
13
573
        PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS)
Line
Count
Source
782
573
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (782:41): [True: 0, False: 573]
11486
0
        int value = _PyLong_AsInt(arg);
11487
0
        if (value == -1 && PyErr_Occurred())
  Branch (11487:13): [True: 0, False: 0]
  Branch (11487:28): [True: 0, False: 0]
11488
0
            return 0;
11489
0
        *valuep = value;
11490
0
        return 1;
11491
0
    }
11492
573
    else {
11493
        /* look up the value in the table using a binary search */
11494
573
        size_t lo = 0;
11495
573
        size_t mid;
11496
573
        size_t hi = tablesize;
11497
573
        int cmp;
11498
573
        const char *confname;
11499
573
        if (!PyUnicode_Check(arg)) {
Line
Count
Source
115
573
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
Line
Count
Source
782
573
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (11499:13): [True: 0, False: 573]
11500
0
            PyErr_SetString(PyExc_TypeError,
11501
0
                "configuration names must be strings or integers");
11502
0
            return 0;
11503
0
        }
11504
573
        confname = PyUnicode_AsUTF8(arg);
11505
573
        if (confname == NULL)
  Branch (11505:13): [True: 0, False: 573]
11506
0
            return 0;
11507
4.52k
        while (lo < hi) {
  Branch (11507:16): [True: 4.52k, False: 1]
11508
4.52k
            mid = (lo + hi) / 2;
11509
4.52k
            cmp = strcmp(confname, table[mid].name);
11510
4.52k
            if (cmp < 0)
  Branch (11510:17): [True: 2.82k, False: 1.70k]
11511
2.82k
                hi = mid;
11512
1.70k
            else if (cmp > 0)
  Branch (11512:22): [True: 1.12k, False: 572]
11513
1.12k
                lo = mid + 1;
11514
572
            else {
11515
572
                *valuep = table[mid].value;
11516
572
                return 1;
11517
572
            }
11518
4.52k
        }
11519
1
        PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
11520
1
        return 0;
11521
573
    }
11522
573
}
11523
11524
11525
#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
11526
static struct constdef  posix_constants_pathconf[] = {
11527
#ifdef _PC_ABI_AIO_XFER_MAX
11528
    {"PC_ABI_AIO_XFER_MAX",     _PC_ABI_AIO_XFER_MAX},
11529
#endif
11530
#ifdef _PC_ABI_ASYNC_IO
11531
    {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
11532
#endif
11533
#ifdef _PC_ASYNC_IO
11534
    {"PC_ASYNC_IO",     _PC_ASYNC_IO},
11535
#endif
11536
#ifdef _PC_CHOWN_RESTRICTED
11537
    {"PC_CHOWN_RESTRICTED",     _PC_CHOWN_RESTRICTED},
11538
#endif
11539
#ifdef _PC_FILESIZEBITS
11540
    {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
11541
#endif
11542
#ifdef _PC_LAST
11543
    {"PC_LAST", _PC_LAST},
11544
#endif
11545
#ifdef _PC_LINK_MAX
11546
    {"PC_LINK_MAX",     _PC_LINK_MAX},
11547
#endif
11548
#ifdef _PC_MAX_CANON
11549
    {"PC_MAX_CANON",    _PC_MAX_CANON},
11550
#endif
11551
#ifdef _PC_MAX_INPUT
11552
    {"PC_MAX_INPUT",    _PC_MAX_INPUT},
11553
#endif
11554
#ifdef _PC_NAME_MAX
11555
    {"PC_NAME_MAX",     _PC_NAME_MAX},
11556
#endif
11557
#ifdef _PC_NO_TRUNC
11558
    {"PC_NO_TRUNC",     _PC_NO_TRUNC},
11559
#endif
11560
#ifdef _PC_PATH_MAX
11561
    {"PC_PATH_MAX",     _PC_PATH_MAX},
11562
#endif
11563
#ifdef _PC_PIPE_BUF
11564
    {"PC_PIPE_BUF",     _PC_PIPE_BUF},
11565
#endif
11566
#ifdef _PC_PRIO_IO
11567
    {"PC_PRIO_IO",      _PC_PRIO_IO},
11568
#endif
11569
#ifdef _PC_SOCK_MAXBUF
11570
    {"PC_SOCK_MAXBUF",  _PC_SOCK_MAXBUF},
11571
#endif
11572
#ifdef _PC_SYNC_IO
11573
    {"PC_SYNC_IO",      _PC_SYNC_IO},
11574
#endif
11575
#ifdef _PC_VDISABLE
11576
    {"PC_VDISABLE",     _PC_VDISABLE},
11577
#endif
11578
#ifdef _PC_ACL_ENABLED
11579
    {"PC_ACL_ENABLED",  _PC_ACL_ENABLED},
11580
#endif
11581
#ifdef _PC_MIN_HOLE_SIZE
11582
    {"PC_MIN_HOLE_SIZE",    _PC_MIN_HOLE_SIZE},
11583
#endif
11584
#ifdef _PC_ALLOC_SIZE_MIN
11585
    {"PC_ALLOC_SIZE_MIN",   _PC_ALLOC_SIZE_MIN},
11586
#endif
11587
#ifdef _PC_REC_INCR_XFER_SIZE
11588
    {"PC_REC_INCR_XFER_SIZE",   _PC_REC_INCR_XFER_SIZE},
11589
#endif
11590
#ifdef _PC_REC_MAX_XFER_SIZE
11591
    {"PC_REC_MAX_XFER_SIZE",    _PC_REC_MAX_XFER_SIZE},
11592
#endif
11593
#ifdef _PC_REC_MIN_XFER_SIZE
11594
    {"PC_REC_MIN_XFER_SIZE",    _PC_REC_MIN_XFER_SIZE},
11595
#endif
11596
#ifdef _PC_REC_XFER_ALIGN
11597
    {"PC_REC_XFER_ALIGN",   _PC_REC_XFER_ALIGN},
11598
#endif
11599
#ifdef _PC_SYMLINK_MAX
11600
    {"PC_SYMLINK_MAX",  _PC_SYMLINK_MAX},
11601
#endif
11602
#ifdef _PC_XATTR_ENABLED
11603
    {"PC_XATTR_ENABLED",    _PC_XATTR_ENABLED},
11604
#endif
11605
#ifdef _PC_XATTR_EXISTS
11606
    {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
11607
#endif
11608
#ifdef _PC_TIMESTAMP_RESOLUTION
11609
    {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
11610
#endif
11611
};
11612
11613
static int
11614
conv_path_confname(PyObject *arg, int *valuep)
11615
2
{
11616
2
    return conv_confname(arg, valuep, posix_constants_pathconf,
11617
2
                         sizeof(posix_constants_pathconf)
11618
2
                           / sizeof(struct constdef));
11619
2
}
11620
#endif
11621
11622
11623
#ifdef HAVE_FPATHCONF
11624
/*[clinic input]
11625
os.fpathconf -> long
11626
11627
    fd: fildes
11628
    name: path_confname
11629
    /
11630
11631
Return the configuration limit name for the file descriptor fd.
11632
11633
If there is no limit, return -1.
11634
[clinic start generated code]*/
11635
11636
static long
11637
os_fpathconf_impl(PyObject *module, int fd, int name)
11638
/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/
11639
1
{
11640
1
    long limit;
11641
11642
1
    errno = 0;
11643
1
    limit = fpathconf(fd, name);
11644
1
    if (limit == -1 && errno != 0)
  Branch (11644:9): [True: 1, False: 0]
  Branch (11644:24): [True: 1, False: 0]
11645
1
        posix_error();
11646
11647
1
    return limit;
11648
1
}
11649
#endif /* HAVE_FPATHCONF */
11650
11651
11652
#ifdef HAVE_PATHCONF
11653
/*[clinic input]
11654
os.pathconf -> long
11655
    path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11656
    name: path_confname
11657
11658
Return the configuration limit name for the file or directory path.
11659
11660
If there is no limit, return -1.
11661
On some platforms, path may also be specified as an open file descriptor.
11662
  If this functionality is unavailable, using it raises an exception.
11663
[clinic start generated code]*/
11664
11665
static long
11666
os_pathconf_impl(PyObject *module, path_t *path, int name)
11667
/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
11668
1
{
11669
1
    long limit;
11670
11671
1
    errno = 0;
11672
1
#ifdef HAVE_FPATHCONF
11673
1
    if (path->fd != -1)
  Branch (11673:9): [True: 1, False: 0]
11674
1
        limit = fpathconf(path->fd, name);
11675
0
    else
11676
0
#endif
11677
0
        limit = pathconf(path->narrow, name);
11678
1
    if (limit == -1 && errno != 0) {
  Branch (11678:9): [True: 1, False: 0]
  Branch (11678:24): [True: 1, False: 0]
11679
1
        if (errno == EINVAL)
  Branch (11679:13): [True: 0, False: 1]
11680
            /* could be a path or name problem */
11681
0
            posix_error();
11682
1
        else
11683
1
            path_error(path);
11684
1
    }
11685
11686
1
    return limit;
11687
1
}
11688
#endif /* HAVE_PATHCONF */
11689
11690
#ifdef HAVE_CONFSTR
11691
static struct constdef posix_constants_confstr[] = {
11692
#ifdef _CS_ARCHITECTURE
11693
    {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
11694
#endif
11695
#ifdef _CS_GNU_LIBC_VERSION
11696
    {"CS_GNU_LIBC_VERSION",     _CS_GNU_LIBC_VERSION},
11697
#endif
11698
#ifdef _CS_GNU_LIBPTHREAD_VERSION
11699
    {"CS_GNU_LIBPTHREAD_VERSION",       _CS_GNU_LIBPTHREAD_VERSION},
11700
#endif
11701
#ifdef _CS_HOSTNAME
11702
    {"CS_HOSTNAME",     _CS_HOSTNAME},
11703
#endif
11704
#ifdef _CS_HW_PROVIDER
11705
    {"CS_HW_PROVIDER",  _CS_HW_PROVIDER},
11706
#endif
11707
#ifdef _CS_HW_SERIAL
11708
    {"CS_HW_SERIAL",    _CS_HW_SERIAL},
11709
#endif
11710
#ifdef _CS_INITTAB_NAME
11711
    {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
11712
#endif
11713
#ifdef _CS_LFS64_CFLAGS
11714
    {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
11715
#endif
11716
#ifdef _CS_LFS64_LDFLAGS
11717
    {"CS_LFS64_LDFLAGS",        _CS_LFS64_LDFLAGS},
11718
#endif
11719
#ifdef _CS_LFS64_LIBS
11720
    {"CS_LFS64_LIBS",   _CS_LFS64_LIBS},
11721
#endif
11722
#ifdef _CS_LFS64_LINTFLAGS
11723
    {"CS_LFS64_LINTFLAGS",      _CS_LFS64_LINTFLAGS},
11724
#endif
11725
#ifdef _CS_LFS_CFLAGS
11726
    {"CS_LFS_CFLAGS",   _CS_LFS_CFLAGS},
11727
#endif
11728
#ifdef _CS_LFS_LDFLAGS
11729
    {"CS_LFS_LDFLAGS",  _CS_LFS_LDFLAGS},
11730
#endif
11731
#ifdef _CS_LFS_LIBS
11732
    {"CS_LFS_LIBS",     _CS_LFS_LIBS},
11733
#endif
11734
#ifdef _CS_LFS_LINTFLAGS
11735
    {"CS_LFS_LINTFLAGS",        _CS_LFS_LINTFLAGS},
11736
#endif
11737
#ifdef _CS_MACHINE
11738
    {"CS_MACHINE",      _CS_MACHINE},
11739
#endif
11740
#ifdef _CS_PATH
11741
    {"CS_PATH", _CS_PATH},
11742
#endif
11743
#ifdef _CS_RELEASE
11744
    {"CS_RELEASE",      _CS_RELEASE},
11745
#endif
11746
#ifdef _CS_SRPC_DOMAIN
11747
    {"CS_SRPC_DOMAIN",  _CS_SRPC_DOMAIN},
11748
#endif
11749
#ifdef _CS_SYSNAME
11750
    {"CS_SYSNAME",      _CS_SYSNAME},
11751
#endif
11752
#ifdef _CS_VERSION
11753
    {"CS_VERSION",      _CS_VERSION},
11754
#endif
11755
#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
11756
    {"CS_XBS5_ILP32_OFF32_CFLAGS",      _CS_XBS5_ILP32_OFF32_CFLAGS},
11757
#endif
11758
#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
11759
    {"CS_XBS5_ILP32_OFF32_LDFLAGS",     _CS_XBS5_ILP32_OFF32_LDFLAGS},
11760
#endif
11761
#ifdef _CS_XBS5_ILP32_OFF32_LIBS
11762
    {"CS_XBS5_ILP32_OFF32_LIBS",        _CS_XBS5_ILP32_OFF32_LIBS},
11763
#endif
11764
#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
11765
    {"CS_XBS5_ILP32_OFF32_LINTFLAGS",   _CS_XBS5_ILP32_OFF32_LINTFLAGS},
11766
#endif
11767
#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
11768
    {"CS_XBS5_ILP32_OFFBIG_CFLAGS",     _CS_XBS5_ILP32_OFFBIG_CFLAGS},
11769
#endif
11770
#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
11771
    {"CS_XBS5_ILP32_OFFBIG_LDFLAGS",    _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
11772
#endif
11773
#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
11774
    {"CS_XBS5_ILP32_OFFBIG_LIBS",       _CS_XBS5_ILP32_OFFBIG_LIBS},
11775
#endif
11776
#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
11777
    {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS",  _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
11778
#endif
11779
#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
11780
    {"CS_XBS5_LP64_OFF64_CFLAGS",       _CS_XBS5_LP64_OFF64_CFLAGS},
11781
#endif
11782
#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
11783
    {"CS_XBS5_LP64_OFF64_LDFLAGS",      _CS_XBS5_LP64_OFF64_LDFLAGS},
11784
#endif
11785
#ifdef _CS_XBS5_LP64_OFF64_LIBS
11786
    {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
11787
#endif
11788
#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
11789
    {"CS_XBS5_LP64_OFF64_LINTFLAGS",    _CS_XBS5_LP64_OFF64_LINTFLAGS},
11790
#endif
11791
#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
11792
    {"CS_XBS5_LPBIG_OFFBIG_CFLAGS",     _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
11793
#endif
11794
#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
11795
    {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS",    _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
11796
#endif
11797
#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
11798
    {"CS_XBS5_LPBIG_OFFBIG_LIBS",       _CS_XBS5_LPBIG_OFFBIG_LIBS},
11799
#endif
11800
#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
11801
    {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS",  _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
11802
#endif
11803
#ifdef _MIPS_CS_AVAIL_PROCESSORS
11804
    {"MIPS_CS_AVAIL_PROCESSORS",        _MIPS_CS_AVAIL_PROCESSORS},
11805
#endif
11806
#ifdef _MIPS_CS_BASE
11807
    {"MIPS_CS_BASE",    _MIPS_CS_BASE},
11808
#endif
11809
#ifdef _MIPS_CS_HOSTID
11810
    {"MIPS_CS_HOSTID",  _MIPS_CS_HOSTID},
11811
#endif
11812
#ifdef _MIPS_CS_HW_NAME
11813
    {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
11814
#endif
11815
#ifdef _MIPS_CS_NUM_PROCESSORS
11816
    {"MIPS_CS_NUM_PROCESSORS",  _MIPS_CS_NUM_PROCESSORS},
11817
#endif
11818
#ifdef _MIPS_CS_OSREL_MAJ
11819
    {"MIPS_CS_OSREL_MAJ",       _MIPS_CS_OSREL_MAJ},
11820
#endif
11821
#ifdef _MIPS_CS_OSREL_MIN
11822
    {"MIPS_CS_OSREL_MIN",       _MIPS_CS_OSREL_MIN},
11823
#endif
11824
#ifdef _MIPS_CS_OSREL_PATCH
11825
    {"MIPS_CS_OSREL_PATCH",     _MIPS_CS_OSREL_PATCH},
11826
#endif
11827
#ifdef _MIPS_CS_OS_NAME
11828
    {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
11829
#endif
11830
#ifdef _MIPS_CS_OS_PROVIDER
11831
    {"MIPS_CS_OS_PROVIDER",     _MIPS_CS_OS_PROVIDER},
11832
#endif
11833
#ifdef _MIPS_CS_PROCESSORS
11834
    {"MIPS_CS_PROCESSORS",      _MIPS_CS_PROCESSORS},
11835
#endif
11836
#ifdef _MIPS_CS_SERIAL
11837
    {"MIPS_CS_SERIAL",  _MIPS_CS_SERIAL},
11838
#endif
11839
#ifdef _MIPS_CS_VENDOR
11840
    {"MIPS_CS_VENDOR",  _MIPS_CS_VENDOR},
11841
#endif
11842
};
11843
11844
static int
11845
conv_confstr_confname(PyObject *arg, int *valuep)
11846
11
{
11847
11
    return conv_confname(arg, valuep, posix_constants_confstr,
11848
11
                         sizeof(posix_constants_confstr)
11849
11
                           / sizeof(struct constdef));
11850
11
}
11851
11852
11853
/*[clinic input]
11854
os.confstr
11855
11856
    name: confstr_confname
11857
    /
11858
11859
Return a string-valued system configuration variable.
11860
[clinic start generated code]*/
11861
11862
static PyObject *
11863
os_confstr_impl(PyObject *module, int name)
11864
/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
11865
10
{
11866
10
    PyObject *result = NULL;
11867
10
    char buffer[255];
11868
10
    size_t len;
11869
11870
10
    errno = 0;
11871
10
    len = confstr(name, buffer, sizeof(buffer));
11872
10
    if (len == 0) {
  Branch (11872:9): [True: 0, False: 10]
11873
0
        if (errno) {
11874
0
            posix_error();
11875
0
            return NULL;
11876
0
        }
11877
0
        else {
11878
0
            Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
11879
0
        }
11880
0
    }
11881
11882
10
    if (len >= sizeof(buffer)) {
  Branch (11882:9): [True: 0, False: 10]
11883
0
        size_t len2;
11884
0
        char *buf = PyMem_Malloc(len);
11885
0
        if (buf == NULL)
  Branch (11885:13): [True: 0, False: 0]
11886
0
            return PyErr_NoMemory();
11887
0
        len2 = confstr(name, buf, len);
11888
0
        assert(len == len2);
11889
0
        result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
11890
0
        PyMem_Free(buf);
11891
0
    }
11892
10
    else
11893
10
        result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
11894
10
    return result;
11895
10
}
11896
#endif /* HAVE_CONFSTR */
11897
11898
11899
#ifdef HAVE_SYSCONF
11900
static struct constdef posix_constants_sysconf[] = {
11901
#ifdef _SC_2_CHAR_TERM
11902
    {"SC_2_CHAR_TERM",  _SC_2_CHAR_TERM},
11903
#endif
11904
#ifdef _SC_2_C_BIND
11905
    {"SC_2_C_BIND",     _SC_2_C_BIND},
11906
#endif
11907
#ifdef _SC_2_C_DEV
11908
    {"SC_2_C_DEV",      _SC_2_C_DEV},
11909
#endif
11910
#ifdef _SC_2_C_VERSION
11911
    {"SC_2_C_VERSION",  _SC_2_C_VERSION},
11912
#endif
11913
#ifdef _SC_2_FORT_DEV
11914
    {"SC_2_FORT_DEV",   _SC_2_FORT_DEV},
11915
#endif
11916
#ifdef _SC_2_FORT_RUN
11917
    {"SC_2_FORT_RUN",   _SC_2_FORT_RUN},
11918
#endif
11919
#ifdef _SC_2_LOCALEDEF
11920
    {"SC_2_LOCALEDEF",  _SC_2_LOCALEDEF},
11921
#endif
11922
#ifdef _SC_2_SW_DEV
11923
    {"SC_2_SW_DEV",     _SC_2_SW_DEV},
11924
#endif
11925
#ifdef _SC_2_UPE
11926
    {"SC_2_UPE",        _SC_2_UPE},
11927
#endif
11928
#ifdef _SC_2_VERSION
11929
    {"SC_2_VERSION",    _SC_2_VERSION},
11930
#endif
11931
#ifdef _SC_ABI_ASYNCHRONOUS_IO
11932
    {"SC_ABI_ASYNCHRONOUS_IO",  _SC_ABI_ASYNCHRONOUS_IO},
11933
#endif
11934
#ifdef _SC_ACL
11935
    {"SC_ACL",  _SC_ACL},
11936
#endif
11937
#ifdef _SC_AIO_LISTIO_MAX
11938
    {"SC_AIO_LISTIO_MAX",       _SC_AIO_LISTIO_MAX},
11939
#endif
11940
#ifdef _SC_AIO_MAX
11941
    {"SC_AIO_MAX",      _SC_AIO_MAX},
11942
#endif
11943
#ifdef _SC_AIO_PRIO_DELTA_MAX
11944
    {"SC_AIO_PRIO_DELTA_MAX",   _SC_AIO_PRIO_DELTA_MAX},
11945
#endif
11946
#ifdef _SC_ARG_MAX
11947
    {"SC_ARG_MAX",      _SC_ARG_MAX},
11948
#endif
11949
#ifdef _SC_ASYNCHRONOUS_IO
11950
    {"SC_ASYNCHRONOUS_IO",      _SC_ASYNCHRONOUS_IO},
11951
#endif
11952
#ifdef _SC_ATEXIT_MAX
11953
    {"SC_ATEXIT_MAX",   _SC_ATEXIT_MAX},
11954
#endif
11955
#ifdef _SC_AUDIT
11956
    {"SC_AUDIT",        _SC_AUDIT},
11957
#endif
11958
#ifdef _SC_AVPHYS_PAGES
11959
    {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
11960
#endif
11961
#ifdef _SC_BC_BASE_MAX
11962
    {"SC_BC_BASE_MAX",  _SC_BC_BASE_MAX},
11963
#endif
11964
#ifdef _SC_BC_DIM_MAX
11965
    {"SC_BC_DIM_MAX",   _SC_BC_DIM_MAX},
11966
#endif
11967
#ifdef _SC_BC_SCALE_MAX
11968
    {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
11969
#endif
11970
#ifdef _SC_BC_STRING_MAX
11971
    {"SC_BC_STRING_MAX",        _SC_BC_STRING_MAX},
11972
#endif
11973
#ifdef _SC_CAP
11974
    {"SC_CAP",  _SC_CAP},
11975
#endif
11976
#ifdef _SC_CHARCLASS_NAME_MAX
11977
    {"SC_CHARCLASS_NAME_MAX",   _SC_CHARCLASS_NAME_MAX},
11978
#endif
11979
#ifdef _SC_CHAR_BIT
11980
    {"SC_CHAR_BIT",     _SC_CHAR_BIT},
11981
#endif
11982
#ifdef _SC_CHAR_MAX
11983
    {"SC_CHAR_MAX",     _SC_CHAR_MAX},
11984
#endif
11985
#ifdef _SC_CHAR_MIN
11986
    {"SC_CHAR_MIN",     _SC_CHAR_MIN},
11987
#endif
11988
#ifdef _SC_CHILD_MAX
11989
    {"SC_CHILD_MAX",    _SC_CHILD_MAX},
11990
#endif
11991
#ifdef _SC_CLK_TCK
11992
    {"SC_CLK_TCK",      _SC_CLK_TCK},
11993
#endif
11994
#ifdef _SC_COHER_BLKSZ
11995
    {"SC_COHER_BLKSZ",  _SC_COHER_BLKSZ},
11996
#endif
11997
#ifdef _SC_COLL_WEIGHTS_MAX
11998
    {"SC_COLL_WEIGHTS_MAX",     _SC_COLL_WEIGHTS_MAX},
11999
#endif
12000
#ifdef _SC_DCACHE_ASSOC
12001
    {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
12002
#endif
12003
#ifdef _SC_DCACHE_BLKSZ
12004
    {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
12005
#endif
12006
#ifdef _SC_DCACHE_LINESZ
12007
    {"SC_DCACHE_LINESZ",        _SC_DCACHE_LINESZ},
12008
#endif
12009
#ifdef _SC_DCACHE_SZ
12010
    {"SC_DCACHE_SZ",    _SC_DCACHE_SZ},
12011
#endif
12012
#ifdef _SC_DCACHE_TBLKSZ
12013
    {"SC_DCACHE_TBLKSZ",        _SC_DCACHE_TBLKSZ},
12014
#endif
12015
#ifdef _SC_DELAYTIMER_MAX
12016
    {"SC_DELAYTIMER_MAX",       _SC_DELAYTIMER_MAX},
12017
#endif
12018
#ifdef _SC_EQUIV_CLASS_MAX
12019
    {"SC_EQUIV_CLASS_MAX",      _SC_EQUIV_CLASS_MAX},
12020
#endif
12021
#ifdef _SC_EXPR_NEST_MAX
12022
    {"SC_EXPR_NEST_MAX",        _SC_EXPR_NEST_MAX},
12023
#endif
12024
#ifdef _SC_FSYNC
12025
    {"SC_FSYNC",        _SC_FSYNC},
12026
#endif
12027
#ifdef _SC_GETGR_R_SIZE_MAX
12028
    {"SC_GETGR_R_SIZE_MAX",     _SC_GETGR_R_SIZE_MAX},
12029
#endif
12030
#ifdef _SC_GETPW_R_SIZE_MAX
12031
    {"SC_GETPW_R_SIZE_MAX",     _SC_GETPW_R_SIZE_MAX},
12032
#endif
12033
#ifdef _SC_ICACHE_ASSOC
12034
    {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
12035
#endif
12036
#ifdef _SC_ICACHE_BLKSZ
12037
    {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
12038
#endif
12039
#ifdef _SC_ICACHE_LINESZ
12040
    {"SC_ICACHE_LINESZ",        _SC_ICACHE_LINESZ},
12041
#endif
12042
#ifdef _SC_ICACHE_SZ
12043
    {"SC_ICACHE_SZ",    _SC_ICACHE_SZ},
12044
#endif
12045
#ifdef _SC_INF
12046
    {"SC_INF",  _SC_INF},
12047
#endif
12048
#ifdef _SC_INT_MAX
12049
    {"SC_INT_MAX",      _SC_INT_MAX},
12050
#endif
12051
#ifdef _SC_INT_MIN
12052
    {"SC_INT_MIN",      _SC_INT_MIN},
12053
#endif
12054
#ifdef _SC_IOV_MAX
12055
    {"SC_IOV_MAX",      _SC_IOV_MAX},
12056
#endif
12057
#ifdef _SC_IP_SECOPTS
12058
    {"SC_IP_SECOPTS",   _SC_IP_SECOPTS},
12059
#endif
12060
#ifdef _SC_JOB_CONTROL
12061
    {"SC_JOB_CONTROL",  _SC_JOB_CONTROL},
12062
#endif
12063
#ifdef _SC_KERN_POINTERS
12064
    {"SC_KERN_POINTERS",        _SC_KERN_POINTERS},
12065
#endif
12066
#ifdef _SC_KERN_SIM
12067
    {"SC_KERN_SIM",     _SC_KERN_SIM},
12068
#endif
12069
#ifdef _SC_LINE_MAX
12070
    {"SC_LINE_MAX",     _SC_LINE_MAX},
12071
#endif
12072
#ifdef _SC_LOGIN_NAME_MAX
12073
    {"SC_LOGIN_NAME_MAX",       _SC_LOGIN_NAME_MAX},
12074
#endif
12075
#ifdef _SC_LOGNAME_MAX
12076
    {"SC_LOGNAME_MAX",  _SC_LOGNAME_MAX},
12077
#endif
12078
#ifdef _SC_LONG_BIT
12079
    {"SC_LONG_BIT",     _SC_LONG_BIT},
12080
#endif
12081
#ifdef _SC_MAC
12082
    {"SC_MAC",  _SC_MAC},
12083
#endif
12084
#ifdef _SC_MAPPED_FILES
12085
    {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
12086
#endif
12087
#ifdef _SC_MAXPID
12088
    {"SC_MAXPID",       _SC_MAXPID},
12089
#endif
12090
#ifdef _SC_MB_LEN_MAX
12091
    {"SC_MB_LEN_MAX",   _SC_MB_LEN_MAX},
12092
#endif
12093
#ifdef _SC_MEMLOCK
12094
    {"SC_MEMLOCK",      _SC_MEMLOCK},
12095
#endif
12096
#ifdef _SC_MEMLOCK_RANGE
12097
    {"SC_MEMLOCK_RANGE",        _SC_MEMLOCK_RANGE},
12098
#endif
12099
#ifdef _SC_MEMORY_PROTECTION
12100
    {"SC_MEMORY_PROTECTION",    _SC_MEMORY_PROTECTION},
12101
#endif
12102
#ifdef _SC_MESSAGE_PASSING
12103
    {"SC_MESSAGE_PASSING",      _SC_MESSAGE_PASSING},
12104
#endif
12105
#ifdef _SC_MMAP_FIXED_ALIGNMENT
12106
    {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
12107
#endif
12108
#ifdef _SC_MQ_OPEN_MAX
12109
    {"SC_MQ_OPEN_MAX",  _SC_MQ_OPEN_MAX},
12110
#endif
12111
#ifdef _SC_MQ_PRIO_MAX
12112
    {"SC_MQ_PRIO_MAX",  _SC_MQ_PRIO_MAX},
12113
#endif
12114
#ifdef _SC_NACLS_MAX
12115
    {"SC_NACLS_MAX",    _SC_NACLS_MAX},
12116
#endif
12117
#ifdef _SC_NGROUPS_MAX
12118
    {"SC_NGROUPS_MAX",  _SC_NGROUPS_MAX},
12119
#endif
12120
#ifdef _SC_NL_ARGMAX
12121
    {"SC_NL_ARGMAX",    _SC_NL_ARGMAX},
12122
#endif
12123
#ifdef _SC_NL_LANGMAX
12124
    {"SC_NL_LANGMAX",   _SC_NL_LANGMAX},
12125
#endif
12126
#ifdef _SC_NL_MSGMAX
12127
    {"SC_NL_MSGMAX",    _SC_NL_MSGMAX},
12128
#endif
12129
#ifdef _SC_NL_NMAX
12130
    {"SC_NL_NMAX",      _SC_NL_NMAX},
12131
#endif
12132
#ifdef _SC_NL_SETMAX
12133
    {"SC_NL_SETMAX",    _SC_NL_SETMAX},
12134
#endif
12135
#ifdef _SC_NL_TEXTMAX
12136
    {"SC_NL_TEXTMAX",   _SC_NL_TEXTMAX},
12137
#endif
12138
#ifdef _SC_NPROCESSORS_CONF
12139
    {"SC_NPROCESSORS_CONF",     _SC_NPROCESSORS_CONF},
12140
#endif
12141
#ifdef _SC_NPROCESSORS_ONLN
12142
    {"SC_NPROCESSORS_ONLN",     _SC_NPROCESSORS_ONLN},
12143
#endif
12144
#ifdef _SC_NPROC_CONF
12145
    {"SC_NPROC_CONF",   _SC_NPROC_CONF},
12146
#endif
12147
#ifdef _SC_NPROC_ONLN
12148
    {"SC_NPROC_ONLN",   _SC_NPROC_ONLN},
12149
#endif
12150
#ifdef _SC_NZERO
12151
    {"SC_NZERO",        _SC_NZERO},
12152
#endif
12153
#ifdef _SC_OPEN_MAX
12154
    {"SC_OPEN_MAX",     _SC_OPEN_MAX},
12155
#endif
12156
#ifdef _SC_PAGESIZE
12157
    {"SC_PAGESIZE",     _SC_PAGESIZE},
12158
#endif
12159
#ifdef _SC_PAGE_SIZE
12160
    {"SC_PAGE_SIZE",    _SC_PAGE_SIZE},
12161
#endif
12162
#ifdef _SC_AIX_REALMEM
12163
    {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
12164
#endif
12165
#ifdef _SC_PASS_MAX
12166
    {"SC_PASS_MAX",     _SC_PASS_MAX},
12167
#endif
12168
#ifdef _SC_PHYS_PAGES
12169
    {"SC_PHYS_PAGES",   _SC_PHYS_PAGES},
12170
#endif
12171
#ifdef _SC_PII
12172
    {"SC_PII",  _SC_PII},
12173
#endif
12174
#ifdef _SC_PII_INTERNET
12175
    {"SC_PII_INTERNET", _SC_PII_INTERNET},
12176
#endif
12177
#ifdef _SC_PII_INTERNET_DGRAM
12178
    {"SC_PII_INTERNET_DGRAM",   _SC_PII_INTERNET_DGRAM},
12179
#endif
12180
#ifdef _SC_PII_INTERNET_STREAM
12181
    {"SC_PII_INTERNET_STREAM",  _SC_PII_INTERNET_STREAM},
12182
#endif
12183
#ifdef _SC_PII_OSI
12184
    {"SC_PII_OSI",      _SC_PII_OSI},
12185
#endif
12186
#ifdef _SC_PII_OSI_CLTS
12187
    {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
12188
#endif
12189
#ifdef _SC_PII_OSI_COTS
12190
    {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
12191
#endif
12192
#ifdef _SC_PII_OSI_M
12193
    {"SC_PII_OSI_M",    _SC_PII_OSI_M},
12194
#endif
12195
#ifdef _SC_PII_SOCKET
12196
    {"SC_PII_SOCKET",   _SC_PII_SOCKET},
12197
#endif
12198
#ifdef _SC_PII_XTI
12199
    {"SC_PII_XTI",      _SC_PII_XTI},
12200
#endif
12201
#ifdef _SC_POLL
12202
    {"SC_POLL", _SC_POLL},
12203
#endif
12204
#ifdef _SC_PRIORITIZED_IO
12205
    {"SC_PRIORITIZED_IO",       _SC_PRIORITIZED_IO},
12206
#endif
12207
#ifdef _SC_PRIORITY_SCHEDULING
12208
    {"SC_PRIORITY_SCHEDULING",  _SC_PRIORITY_SCHEDULING},
12209
#endif
12210
#ifdef _SC_REALTIME_SIGNALS
12211
    {"SC_REALTIME_SIGNALS",     _SC_REALTIME_SIGNALS},
12212
#endif
12213
#ifdef _SC_RE_DUP_MAX
12214
    {"SC_RE_DUP_MAX",   _SC_RE_DUP_MAX},
12215
#endif
12216
#ifdef _SC_RTSIG_MAX
12217
    {"SC_RTSIG_MAX",    _SC_RTSIG_MAX},
12218
#endif
12219
#ifdef _SC_SAVED_IDS
12220
    {"SC_SAVED_IDS",    _SC_SAVED_IDS},
12221
#endif
12222
#ifdef _SC_SCHAR_MAX
12223
    {"SC_SCHAR_MAX",    _SC_SCHAR_MAX},
12224
#endif
12225
#ifdef _SC_SCHAR_MIN
12226
    {"SC_SCHAR_MIN",    _SC_SCHAR_MIN},
12227
#endif
12228
#ifdef _SC_SELECT
12229
    {"SC_SELECT",       _SC_SELECT},
12230
#endif
12231
#ifdef _SC_SEMAPHORES
12232
    {"SC_SEMAPHORES",   _SC_SEMAPHORES},
12233
#endif
12234
#ifdef _SC_SEM_NSEMS_MAX
12235
    {"SC_SEM_NSEMS_MAX",        _SC_SEM_NSEMS_MAX},
12236
#endif
12237
#ifdef _SC_SEM_VALUE_MAX
12238
    {"SC_SEM_VALUE_MAX",        _SC_SEM_VALUE_MAX},
12239
#endif
12240
#ifdef _SC_SHARED_MEMORY_OBJECTS
12241
    {"SC_SHARED_MEMORY_OBJECTS",        _SC_SHARED_MEMORY_OBJECTS},
12242
#endif
12243
#ifdef _SC_SHRT_MAX
12244
    {"SC_SHRT_MAX",     _SC_SHRT_MAX},
12245
#endif
12246
#ifdef _SC_SHRT_MIN
12247
    {"SC_SHRT_MIN",     _SC_SHRT_MIN},
12248
#endif
12249
#ifdef _SC_SIGQUEUE_MAX
12250
    {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
12251
#endif
12252
#ifdef _SC_SIGRT_MAX
12253
    {"SC_SIGRT_MAX",    _SC_SIGRT_MAX},
12254
#endif
12255
#ifdef _SC_SIGRT_MIN
12256
    {"SC_SIGRT_MIN",    _SC_SIGRT_MIN},
12257
#endif
12258
#ifdef _SC_SOFTPOWER
12259
    {"SC_SOFTPOWER",    _SC_SOFTPOWER},
12260
#endif
12261
#ifdef _SC_SPLIT_CACHE
12262
    {"SC_SPLIT_CACHE",  _SC_SPLIT_CACHE},
12263
#endif
12264
#ifdef _SC_SSIZE_MAX
12265
    {"SC_SSIZE_MAX",    _SC_SSIZE_MAX},
12266
#endif
12267
#ifdef _SC_STACK_PROT
12268
    {"SC_STACK_PROT",   _SC_STACK_PROT},
12269
#endif
12270
#ifdef _SC_STREAM_MAX
12271
    {"SC_STREAM_MAX",   _SC_STREAM_MAX},
12272
#endif
12273
#ifdef _SC_SYNCHRONIZED_IO
12274
    {"SC_SYNCHRONIZED_IO",      _SC_SYNCHRONIZED_IO},
12275
#endif
12276
#ifdef _SC_THREADS
12277
    {"SC_THREADS",      _SC_THREADS},
12278
#endif
12279
#ifdef _SC_THREAD_ATTR_STACKADDR
12280
    {"SC_THREAD_ATTR_STACKADDR",        _SC_THREAD_ATTR_STACKADDR},
12281
#endif
12282
#ifdef _SC_THREAD_ATTR_STACKSIZE
12283
    {"SC_THREAD_ATTR_STACKSIZE",        _SC_THREAD_ATTR_STACKSIZE},
12284
#endif
12285
#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
12286
    {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
12287
#endif
12288
#ifdef _SC_THREAD_KEYS_MAX
12289
    {"SC_THREAD_KEYS_MAX",      _SC_THREAD_KEYS_MAX},
12290
#endif
12291
#ifdef _SC_THREAD_PRIORITY_SCHEDULING
12292
    {"SC_THREAD_PRIORITY_SCHEDULING",   _SC_THREAD_PRIORITY_SCHEDULING},
12293
#endif
12294
#ifdef _SC_THREAD_PRIO_INHERIT
12295
    {"SC_THREAD_PRIO_INHERIT",  _SC_THREAD_PRIO_INHERIT},
12296
#endif
12297
#ifdef _SC_THREAD_PRIO_PROTECT
12298
    {"SC_THREAD_PRIO_PROTECT",  _SC_THREAD_PRIO_PROTECT},
12299
#endif
12300
#ifdef _SC_THREAD_PROCESS_SHARED
12301
    {"SC_THREAD_PROCESS_SHARED",        _SC_THREAD_PROCESS_SHARED},
12302
#endif
12303
#ifdef _SC_THREAD_SAFE_FUNCTIONS
12304
    {"SC_THREAD_SAFE_FUNCTIONS",        _SC_THREAD_SAFE_FUNCTIONS},
12305
#endif
12306
#ifdef _SC_THREAD_STACK_MIN
12307
    {"SC_THREAD_STACK_MIN",     _SC_THREAD_STACK_MIN},
12308
#endif
12309
#ifdef _SC_THREAD_THREADS_MAX
12310
    {"SC_THREAD_THREADS_MAX",   _SC_THREAD_THREADS_MAX},
12311
#endif
12312
#ifdef _SC_TIMERS
12313
    {"SC_TIMERS",       _SC_TIMERS},
12314
#endif
12315
#ifdef _SC_TIMER_MAX
12316
    {"SC_TIMER_MAX",    _SC_TIMER_MAX},
12317
#endif
12318
#ifdef _SC_TTY_NAME_MAX
12319
    {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
12320
#endif
12321
#ifdef _SC_TZNAME_MAX
12322
    {"SC_TZNAME_MAX",   _SC_TZNAME_MAX},
12323
#endif
12324
#ifdef _SC_T_IOV_MAX
12325
    {"SC_T_IOV_MAX",    _SC_T_IOV_MAX},
12326
#endif
12327
#ifdef _SC_UCHAR_MAX
12328
    {"SC_UCHAR_MAX",    _SC_UCHAR_MAX},
12329
#endif
12330
#ifdef _SC_UINT_MAX
12331
    {"SC_UINT_MAX",     _SC_UINT_MAX},
12332
#endif
12333
#ifdef _SC_UIO_MAXIOV
12334
    {"SC_UIO_MAXIOV",   _SC_UIO_MAXIOV},
12335
#endif
12336
#ifdef _SC_ULONG_MAX
12337
    {"SC_ULONG_MAX",    _SC_ULONG_MAX},
12338
#endif
12339
#ifdef _SC_USHRT_MAX
12340
    {"SC_USHRT_MAX",    _SC_USHRT_MAX},
12341
#endif
12342
#ifdef _SC_VERSION
12343
    {"SC_VERSION",      _SC_VERSION},
12344
#endif
12345
#ifdef _SC_WORD_BIT
12346
    {"SC_WORD_BIT",     _SC_WORD_BIT},
12347
#endif
12348
#ifdef _SC_XBS5_ILP32_OFF32
12349
    {"SC_XBS5_ILP32_OFF32",     _SC_XBS5_ILP32_OFF32},
12350
#endif
12351
#ifdef _SC_XBS5_ILP32_OFFBIG
12352
    {"SC_XBS5_ILP32_OFFBIG",    _SC_XBS5_ILP32_OFFBIG},
12353
#endif
12354
#ifdef _SC_XBS5_LP64_OFF64
12355
    {"SC_XBS5_LP64_OFF64",      _SC_XBS5_LP64_OFF64},
12356
#endif
12357
#ifdef _SC_XBS5_LPBIG_OFFBIG
12358
    {"SC_XBS5_LPBIG_OFFBIG",    _SC_XBS5_LPBIG_OFFBIG},
12359
#endif
12360
#ifdef _SC_XOPEN_CRYPT
12361
    {"SC_XOPEN_CRYPT",  _SC_XOPEN_CRYPT},
12362
#endif
12363
#ifdef _SC_XOPEN_ENH_I18N
12364
    {"SC_XOPEN_ENH_I18N",       _SC_XOPEN_ENH_I18N},
12365
#endif
12366
#ifdef _SC_XOPEN_LEGACY
12367
    {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
12368
#endif
12369
#ifdef _SC_XOPEN_REALTIME
12370
    {"SC_XOPEN_REALTIME",       _SC_XOPEN_REALTIME},
12371
#endif
12372
#ifdef _SC_XOPEN_REALTIME_THREADS
12373
    {"SC_XOPEN_REALTIME_THREADS",       _SC_XOPEN_REALTIME_THREADS},
12374
#endif
12375
#ifdef _SC_XOPEN_SHM
12376
    {"SC_XOPEN_SHM",    _SC_XOPEN_SHM},
12377
#endif
12378
#ifdef _SC_XOPEN_UNIX
12379
    {"SC_XOPEN_UNIX",   _SC_XOPEN_UNIX},
12380
#endif
12381
#ifdef _SC_XOPEN_VERSION
12382
    {"SC_XOPEN_VERSION",        _SC_XOPEN_VERSION},
12383
#endif
12384
#ifdef _SC_XOPEN_XCU_VERSION
12385
    {"SC_XOPEN_XCU_VERSION",    _SC_XOPEN_XCU_VERSION},
12386
#endif
12387
#ifdef _SC_XOPEN_XPG2
12388
    {"SC_XOPEN_XPG2",   _SC_XOPEN_XPG2},
12389
#endif
12390
#ifdef _SC_XOPEN_XPG3
12391
    {"SC_XOPEN_XPG3",   _SC_XOPEN_XPG3},
12392
#endif
12393
#ifdef _SC_XOPEN_XPG4
12394
    {"SC_XOPEN_XPG4",   _SC_XOPEN_XPG4},
12395
#endif
12396
#ifdef _SC_MINSIGSTKSZ
12397
    {"SC_MINSIGSTKSZ",   _SC_MINSIGSTKSZ},
12398
#endif
12399
};
12400
12401
static int
12402
conv_sysconf_confname(PyObject *arg, int *valuep)
12403
560
{
12404
560
    return conv_confname(arg, valuep, posix_constants_sysconf,
12405
560
                         sizeof(posix_constants_sysconf)
12406
560
                           / sizeof(struct constdef));
12407
560
}
12408
12409
12410
/*[clinic input]
12411
os.sysconf -> long
12412
    name: sysconf_confname
12413
    /
12414
12415
Return an integer-valued system configuration variable.
12416
[clinic start generated code]*/
12417
12418
static long
12419
os_sysconf_impl(PyObject *module, int name)
12420
/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
12421
560
{
12422
560
    long value;
12423
12424
560
    errno = 0;
12425
560
    value = sysconf(name);
12426
560
    if (value == -1 && errno != 0)
  Branch (12426:9): [True: 558, False: 2]
  Branch (12426:24): [True: 0, False: 558]
12427
0
        posix_error();
12428
560
    return value;
12429
560
}
12430
#endif /* HAVE_SYSCONF */
12431
12432
12433
/* This code is used to ensure that the tables of configuration value names
12434
 * are in sorted order as required by conv_confname(), and also to build
12435
 * the exported dictionaries that are used to publish information about the
12436
 * names available on the host platform.
12437
 *
12438
 * Sorting the table at runtime ensures that the table is properly ordered
12439
 * when used, even for platforms we're not able to test on.  It also makes
12440
 * it easier to add additional entries to the tables.
12441
 */
12442
12443
static int
12444
cmp_constdefs(const void *v1,  const void *v2)
12445
156k
{
12446
156k
    const struct constdef *c1 =
12447
156k
    (const struct constdef *) v1;
12448
156k
    const struct constdef *c2 =
12449
156k
    (const struct constdef *) v2;
12450
12451
156k
    return strcmp(c1->name, c2->name);
12452
156k
}
12453
12454
static int
12455
setup_confname_table(struct constdef *table, size_t tablesize,
12456
                     const char *tablename, PyObject *module)
12457
834
{
12458
834
    PyObject *d = NULL;
12459
834
    size_t i;
12460
12461
834
    qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
12462
834
    d = PyDict_New();
12463
834
    if (d == NULL)
  Branch (12463:9): [True: 0, False: 834]
12464
0
        return -1;
12465
12466
51.1k
    for (i=0; i < tablesize; ++i) {
  Branch (12466:15): [True: 50.3k, False: 834]
12467
50.3k
        PyObject *o = PyLong_FromLong(table[i].value);
12468
50.3k
        if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
  Branch (12468:13): [True: 0, False: 50.3k]
  Branch (12468:26): [True: 0, False: 50.3k]
12469
0
            Py_XDECREF(o);
Line
Count
Source
613
0
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
12470
0
            Py_DECREF(d);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
12471
0
            return -1;
12472
0
        }
12473
50.3k
        Py_DECREF(o);
Line
Count
Source
548
50.3k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
50.3k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
50.3k
#  define _Py_CAST(type, expr) ((type)(expr))
12474
50.3k
    }
12475
834
    return PyModule_AddObject(module, tablename, d);
12476
834
}
12477
12478
/* Return -1 on failure, 0 on success. */
12479
static int
12480
setup_confname_tables(PyObject *module)
12481
278
{
12482
278
#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
12483
278
    if (setup_confname_table(posix_constants_pathconf,
  Branch (12483:9): [True: 0, False: 278]
12484
278
                             sizeof(posix_constants_pathconf)
12485
278
                               / sizeof(struct constdef),
12486
278
                             "pathconf_names", module))
12487
0
        return -1;
12488
278
#endif
12489
278
#ifdef HAVE_CONFSTR
12490
278
    if (setup_confname_table(posix_constants_confstr,
  Branch (12490:9): [True: 0, False: 278]
12491
278
                             sizeof(posix_constants_confstr)
12492
278
                               / sizeof(struct constdef),
12493
278
                             "confstr_names", module))
12494
0
        return -1;
12495
278
#endif
12496
278
#ifdef HAVE_SYSCONF
12497
278
    if (setup_confname_table(posix_constants_sysconf,
  Branch (12497:9): [True: 0, False: 278]
12498
278
                             sizeof(posix_constants_sysconf)
12499
278
                               / sizeof(struct constdef),
12500
278
                             "sysconf_names", module))
12501
0
        return -1;
12502
278
#endif
12503
278
    return 0;
12504
278
}
12505
12506
12507
/*[clinic input]
12508
os.abort
12509
12510
Abort the interpreter immediately.
12511
12512
This function 'dumps core' or otherwise fails in the hardest way possible
12513
on the hosting operating system.  This function never returns.
12514
[clinic start generated code]*/
12515
12516
static PyObject *
12517
os_abort_impl(PyObject *module)
12518
/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
12519
0
{
12520
0
    abort();
12521
    /*NOTREACHED*/
12522
#ifndef __clang__
12523
    /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
12524
       GCC emits a warning without "return NULL;" (compiler bug?), but Clang
12525
       is smarter and emits a warning on the return. */
12526
    Py_FatalError("abort() called from Python code didn't abort!");
12527
    return NULL;
12528
#endif
12529
0
}
12530
12531
#ifdef MS_WINDOWS
12532
/* Grab ShellExecute dynamically from shell32 */
12533
static int has_ShellExecute = -1;
12534
static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
12535
                                              LPCWSTR, INT);
12536
static int
12537
check_ShellExecute()
12538
{
12539
    HINSTANCE hShell32;
12540
12541
    /* only recheck */
12542
    if (-1 == has_ShellExecute) {
12543
        Py_BEGIN_ALLOW_THREADS
12544
        /* Security note: this call is not vulnerable to "DLL hijacking".
12545
           SHELL32 is part of "KnownDLLs" and so Windows always load
12546
           the system SHELL32.DLL, even if there is another SHELL32.DLL
12547
           in the DLL search path. */
12548
        hShell32 = LoadLibraryW(L"SHELL32");
12549
        if (hShell32) {
12550
            *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
12551
                                            "ShellExecuteW");
12552
            has_ShellExecute = Py_ShellExecuteW != NULL;
12553
        } else {
12554
            has_ShellExecute = 0;
12555
        }
12556
        Py_END_ALLOW_THREADS
12557
    }
12558
    return has_ShellExecute;
12559
}
12560
12561
12562
/*[clinic input]
12563
os.startfile
12564
    filepath: path_t
12565
    operation: Py_UNICODE = NULL
12566
    arguments: Py_UNICODE = NULL
12567
    cwd: path_t(nullable=True) = None
12568
    show_cmd: int = 1
12569
12570
Start a file with its associated application.
12571
12572
When "operation" is not specified or "open", this acts like
12573
double-clicking the file in Explorer, or giving the file name as an
12574
argument to the DOS "start" command: the file is opened with whatever
12575
application (if any) its extension is associated.
12576
When another "operation" is given, it specifies what should be done with
12577
the file.  A typical operation is "print".
12578
12579
"arguments" is passed to the application, but should be omitted if the
12580
file is a document.
12581
12582
"cwd" is the working directory for the operation. If "filepath" is
12583
relative, it will be resolved against this directory. This argument
12584
should usually be an absolute path.
12585
12586
"show_cmd" can be used to override the recommended visibility option.
12587
See the Windows ShellExecute documentation for values.
12588
12589
startfile returns as soon as the associated application is launched.
12590
There is no option to wait for the application to close, and no way
12591
to retrieve the application's exit status.
12592
12593
The filepath is relative to the current directory.  If you want to use
12594
an absolute path, make sure the first character is not a slash ("/");
12595
the underlying Win32 ShellExecute function doesn't work if it is.
12596
[clinic start generated code]*/
12597
12598
static PyObject *
12599
os_startfile_impl(PyObject *module, path_t *filepath,
12600
                  const Py_UNICODE *operation, const Py_UNICODE *arguments,
12601
                  path_t *cwd, int show_cmd)
12602
/*[clinic end generated code: output=3baa4f9795841880 input=8248997b80669622]*/
12603
{
12604
    HINSTANCE rc;
12605
12606
    if(!check_ShellExecute()) {
12607
        /* If the OS doesn't have ShellExecute, return a
12608
           NotImplementedError. */
12609
        return PyErr_Format(PyExc_NotImplementedError,
12610
            "startfile not available on this platform");
12611
    }
12612
12613
    if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
12614
        return NULL;
12615
    }
12616
    if (PySys_Audit("os.startfile/2", "OuuOi", filepath->object, operation,
12617
                    arguments, cwd->object ? cwd->object : Py_None,
12618
                    show_cmd) < 0) {
12619
        return NULL;
12620
    }
12621
12622
    Py_BEGIN_ALLOW_THREADS
12623
    rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
12624
                          arguments, cwd->wide, show_cmd);
12625
    Py_END_ALLOW_THREADS
12626
12627
    if (rc <= (HINSTANCE)32) {
12628
        win32_error_object("startfile", filepath->object);
12629
        return NULL;
12630
    }
12631
    Py_RETURN_NONE;
12632
}
12633
#endif /* MS_WINDOWS */
12634
12635
12636
#ifdef HAVE_GETLOADAVG
12637
/*[clinic input]
12638
os.getloadavg
12639
12640
Return average recent system load information.
12641
12642
Return the number of processes in the system run queue averaged over
12643
the last 1, 5, and 15 minutes as a tuple of three floats.
12644
Raises OSError if the load average was unobtainable.
12645
[clinic start generated code]*/
12646
12647
static PyObject *
12648
os_getloadavg_impl(PyObject *module)
12649
/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
12650
438
{
12651
438
    double loadavg[3];
12652
438
    if (getloadavg(loadavg, 3)!=3) {
  Branch (12652:9): [True: 0, False: 438]
12653
0
        PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
12654
0
        return NULL;
12655
0
    } else
12656
438
        return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Line
Count
Source
20
438
#define Py_BuildValue                   _Py_BuildValue_SizeT
12657
438
}
12658
#endif /* HAVE_GETLOADAVG */
12659
12660
12661
/*[clinic input]
12662
os.device_encoding
12663
    fd: int
12664
12665
Return a string describing the encoding of a terminal's file descriptor.
12666
12667
The file descriptor must be attached to a terminal.
12668
If the device is not a terminal, return None.
12669
[clinic start generated code]*/
12670
12671
static PyObject *
12672
os_device_encoding_impl(PyObject *module, int fd)
12673
/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
12674
2
{
12675
2
    return _Py_device_encoding(fd);
12676
2
}
12677
12678
12679
#ifdef HAVE_SETRESUID
12680
/*[clinic input]
12681
os.setresuid
12682
12683
    ruid: uid_t
12684
    euid: uid_t
12685
    suid: uid_t
12686
    /
12687
12688
Set the current process's real, effective, and saved user ids.
12689
[clinic start generated code]*/
12690
12691
static PyObject *
12692
os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12693
/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
12694
3
{
12695
3
    if (setresuid(ruid, euid, suid) < 0)
  Branch (12695:9): [True: 1, False: 2]
12696
1
        return posix_error();
12697
3
    Py_RETURN_NONE;
Line
Count
Source
661
2
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
2
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
12698
3
}
12699
#endif /* HAVE_SETRESUID */
12700
12701
12702
#ifdef HAVE_SETRESGID
12703
/*[clinic input]
12704
os.setresgid
12705
12706
    rgid: gid_t
12707
    egid: gid_t
12708
    sgid: gid_t
12709
    /
12710
12711
Set the current process's real, effective, and saved group ids.
12712
[clinic start generated code]*/
12713
12714
static PyObject *
12715
os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12716
/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
12717
3
{
12718
3
    if (setresgid(rgid, egid, sgid) < 0)
  Branch (12718:9): [True: 1, False: 2]
12719
1
        return posix_error();
12720
3
    Py_RETURN_NONE;
Line
Count
Source
661
2
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
2
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
12721
3
}
12722
#endif /* HAVE_SETRESGID */
12723
12724
12725
#ifdef HAVE_GETRESUID
12726
/*[clinic input]
12727
os.getresuid
12728
12729
Return a tuple of the current process's real, effective, and saved user ids.
12730
[clinic start generated code]*/
12731
12732
static PyObject *
12733
os_getresuid_impl(PyObject *module)
12734
/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
12735
3
{
12736
3
    uid_t ruid, euid, suid;
12737
3
    if (getresuid(&ruid, &euid, &suid) < 0)
  Branch (12737:9): [True: 0, False: 3]
12738
0
        return posix_error();
12739
3
    return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
Line
Count
Source
20
3
#define Py_BuildValue                   _Py_BuildValue_SizeT
12740
3
                                  _PyLong_FromUid(euid),
12741
3
                                  _PyLong_FromUid(suid));
12742
3
}
12743
#endif /* HAVE_GETRESUID */
12744
12745
12746
#ifdef HAVE_GETRESGID
12747
/*[clinic input]
12748
os.getresgid
12749
12750
Return a tuple of the current process's real, effective, and saved group ids.
12751
[clinic start generated code]*/
12752
12753
static PyObject *
12754
os_getresgid_impl(PyObject *module)
12755
/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
12756
3
{
12757
3
    gid_t rgid, egid, sgid;
12758
3
    if (getresgid(&rgid, &egid, &sgid) < 0)
  Branch (12758:9): [True: 0, False: 3]
12759
0
        return posix_error();
12760
3
    return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
Line
Count
Source
20
3
#define Py_BuildValue                   _Py_BuildValue_SizeT
12761
3
                                  _PyLong_FromGid(egid),
12762
3
                                  _PyLong_FromGid(sgid));
12763
3
}
12764
#endif /* HAVE_GETRESGID */
12765
12766
12767
#ifdef USE_XATTRS
12768
/*[clinic input]
12769
os.getxattr
12770
12771
    path: path_t(allow_fd=True)
12772
    attribute: path_t
12773
    *
12774
    follow_symlinks: bool = True
12775
12776
Return the value of extended attribute attribute on path.
12777
12778
path may be either a string, a path-like object, or an open file descriptor.
12779
If follow_symlinks is False, and the last element of the path is a symbolic
12780
  link, getxattr will examine the symbolic link itself instead of the file
12781
  the link points to.
12782
12783
[clinic start generated code]*/
12784
12785
static PyObject *
12786
os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
12787
                 int follow_symlinks)
12788
/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
12789
41
{
12790
41
    Py_ssize_t i;
12791
41
    PyObject *buffer = NULL;
12792
12793
41
    if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
  Branch (12793:9): [True: 0, False: 41]
12794
0
        return NULL;
12795
12796
41
    if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
  Branch (12796:9): [True: 0, False: 41]
12797
0
        return NULL;
12798
0
    }
12799
12800
47
    for (i = 0; ; i++) {
12801
47
        void *ptr;
12802
47
        ssize_t result;
12803
47
        static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
12804
47
        Py_ssize_t buffer_size = buffer_sizes[i];
12805
47
        if (!buffer_size) {
  Branch (12805:13): [True: 0, False: 47]
12806
0
            path_error(path);
12807
0
            return NULL;
12808
0
        }
12809
47
        buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12810
47
        if (!buffer)
  Branch (12810:13): [True: 0, False: 47]
12811
0
            return NULL;
12812
47
        ptr = PyBytes_AS_STRING(buffer);
Line
Count
Source
39
47
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
47
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
47
#  define _Py_CAST(type, expr) ((type)(expr))
12813
12814
47
        Py_BEGIN_ALLOW_THREADS;
Line
Count
Source
142
47
#define Py_BEGIN_ALLOW_THREADS { \
143
47
                        PyThreadState *_save; \
144
47
                        _save = PyEval_SaveThread();
12815
47
        if (path->fd >= 0)
  Branch (12815:13): [True: 14, False: 33]
12816
14
            result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
12817
33
        else if (follow_symlinks)
  Branch (12817:18): [True: 19, False: 14]
12818
19
            result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
12819
14
        else
12820
14
            result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
12821
47
        Py_END_ALLOW_THREADS;
Line
Count
Source
147
47
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
47
                 }
12822
12823
47
        if (result < 0) {
  Branch (12823:13): [True: 23, False: 24]
12824
23
            Py_DECREF(buffer);
Line
Count
Source
548
23
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
23
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
23
#  define _Py_CAST(type, expr) ((type)(expr))
12825
23
            if (errno == ERANGE)
  Branch (12825:17): [True: 6, False: 17]
12826
6
                continue;
12827
17
            path_error(path);
12828
17
            return NULL;
12829
23
        }
12830
12831
24
        if (result != buffer_size) {
  Branch (12831:13): [True: 24, False: 0]
12832
            /* Can only shrink. */
12833
24
            _PyBytes_Resize(&buffer, result);
12834
24
        }
12835
24
        break;
12836
47
    }
12837
12838
24
    return buffer;
12839
41
}
12840
12841
12842
/*[clinic input]
12843
os.setxattr
12844
12845
    path: path_t(allow_fd=True)
12846
    attribute: path_t
12847
    value: Py_buffer
12848
    flags: int = 0
12849
    *
12850
    follow_symlinks: bool = True
12851
12852
Set extended attribute attribute on path to value.
12853
12854
path may be either a string, a path-like object,  or an open file descriptor.
12855
If follow_symlinks is False, and the last element of the path is a symbolic
12856
  link, setxattr will modify the symbolic link itself instead of the file
12857
  the link points to.
12858
12859
[clinic start generated code]*/
12860
12861
static PyObject *
12862
os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
12863
                 Py_buffer *value, int flags, int follow_symlinks)
12864
/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
12865
645
{
12866
645
    ssize_t result;
12867
12868
645
    if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
  Branch (12868:9): [True: 0, False: 645]
12869
0
        return NULL;
12870
12871
645
    if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
  Branch (12871:9): [True: 0, False: 645]
12872
645
                    value->buf, value->len, flags) < 0) {
12873
0
        return NULL;
12874
0
    }
12875
12876
645
    Py_BEGIN_ALLOW_THREADS;
Line
Count
Source
142
645
#define Py_BEGIN_ALLOW_THREADS { \
143
645
                        PyThreadState *_save; \
144
645
                        _save = PyEval_SaveThread();
12877
645
    if (path->fd > -1)
  Branch (12877:9): [True: 215, False: 430]
12878
215
        result = fsetxattr(path->fd, attribute->narrow,
12879
215
                           value->buf, value->len, flags);
12880
430
    else if (follow_symlinks)
  Branch (12880:14): [True: 218, False: 212]
12881
218
        result = setxattr(path->narrow, attribute->narrow,
12882
218
                           value->buf, value->len, flags);
12883
212
    else
12884
212
        result = lsetxattr(path->narrow, attribute->narrow,
12885
212
                           value->buf, value->len, flags);
12886
645
    Py_END_ALLOW_THREADS;
Line
Count
Source
147
645
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
645
                 }
12887
12888
645
    if (result) {
  Branch (12888:9): [True: 18, False: 627]
12889
18
        path_error(path);
12890
18
        return NULL;
12891
18
    }
12892
12893
645
    Py_RETURN_NONE;
Line
Count
Source
661
627
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
627
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
627
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
627
#  define _Py_CAST(type, expr) ((type)(expr))
12894
645
}
12895
12896
12897
/*[clinic input]
12898
os.removexattr
12899
12900
    path: path_t(allow_fd=True)
12901
    attribute: path_t
12902
    *
12903
    follow_symlinks: bool = True
12904
12905
Remove extended attribute attribute on path.
12906
12907
path may be either a string, a path-like object, or an open file descriptor.
12908
If follow_symlinks is False, and the last element of the path is a symbolic
12909
  link, removexattr will modify the symbolic link itself instead of the file
12910
  the link points to.
12911
12912
[clinic start generated code]*/
12913
12914
static PyObject *
12915
os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
12916
                    int follow_symlinks)
12917
/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
12918
17
{
12919
17
    ssize_t result;
12920
12921
17
    if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
  Branch (12921:9): [True: 0, False: 17]
12922
0
        return NULL;
12923
12924
17
    if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
  Branch (12924:9): [True: 0, False: 17]
12925
0
        return NULL;
12926
0
    }
12927
12928
17
    Py_BEGIN_ALLOW_THREADS;
Line
Count
Source
142
17
#define Py_BEGIN_ALLOW_THREADS { \
143
17
                        PyThreadState *_save; \
144
17
                        _save = PyEval_SaveThread();
12929
17
    if (path->fd > -1)
  Branch (12929:9): [True: 4, False: 13]
12930
4
        result = fremovexattr(path->fd, attribute->narrow);
12931
13
    else if (follow_symlinks)
  Branch (12931:14): [True: 9, False: 4]
12932
9
        result = removexattr(path->narrow, attribute->narrow);
12933
4
    else
12934
4
        result = lremovexattr(path->narrow, attribute->narrow);
12935
17
    Py_END_ALLOW_THREADS;
Line
Count
Source
147
17
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
17
                 }
12936
12937
17
    if (result) {
  Branch (12937:9): [True: 5, False: 12]
12938
5
        return path_error(path);
12939
5
    }
12940
12941
17
    Py_RETURN_NONE;
Line
Count
Source
661
12
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
12
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
12
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
12
#  define _Py_CAST(type, expr) ((type)(expr))
12942
17
}
12943
12944
12945
/*[clinic input]
12946
os.listxattr
12947
12948
    path: path_t(allow_fd=True, nullable=True) = None
12949
    *
12950
    follow_symlinks: bool = True
12951
12952
Return a list of extended attributes on path.
12953
12954
path may be either None, a string, a path-like object, or an open file descriptor.
12955
if path is None, listxattr will examine the current directory.
12956
If follow_symlinks is False, and the last element of the path is a symbolic
12957
  link, listxattr will examine the symbolic link itself instead of the file
12958
  the link points to.
12959
[clinic start generated code]*/
12960
12961
static PyObject *
12962
os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
12963
/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
12964
8.66k
{
12965
8.66k
    Py_ssize_t i;
12966
8.66k
    PyObject *result = NULL;
12967
8.66k
    const char *name;
12968
8.66k
    char *buffer = NULL;
12969
12970
8.66k
    if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
  Branch (12970:9): [True: 0, False: 8.66k]
12971
0
        goto exit;
12972
12973
8.66k
    if (PySys_Audit("os.listxattr", "(O)",
  Branch (12973:9): [True: 0, False: 8.66k]
12974
8.66k
                    path->object ? path->object : Py_None) < 0) {
Line
Count
Source
654
0
#define Py_None (&_Py_NoneStruct)
  Branch (12974:21): [True: 8.66k, False: 0]
12975
0
        return NULL;
12976
0
    }
12977
12978
8.66k
    name = path->narrow ? path->narrow : ".";
  Branch (12978:12): [True: 8.65k, False: 10]
12979
12980
8.67k
    for (i = 0; ; i++) {
12981
8.67k
        const char *start, *trace, *end;
12982
8.67k
        ssize_t length;
12983
8.67k
        static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
12984
8.67k
        Py_ssize_t buffer_size = buffer_sizes[i];
12985
8.67k
        if (!buffer_size) {
  Branch (12985:13): [True: 0, False: 8.67k]
12986
            /* ERANGE */
12987
0
            path_error(path);
12988
0
            break;
12989
0
        }
12990
8.67k
        buffer = PyMem_Malloc(buffer_size);
12991
8.67k
        if (!buffer) {
  Branch (12991:13): [True: 0, False: 8.67k]
12992
0
            PyErr_NoMemory();
12993
0
            break;
12994
0
        }
12995
12996
8.67k
        Py_BEGIN_ALLOW_THREADS;
Line
Count
Source
142
8.67k
#define Py_BEGIN_ALLOW_THREADS { \
143
8.67k
                        PyThreadState *_save; \
144
8.67k
                        _save = PyEval_SaveThread();
12997
8.67k
        if (path->fd > -1)
  Branch (12997:13): [True: 12, False: 8.65k]
12998
12
            length = flistxattr(path->fd, buffer, buffer_size);
12999
8.65k
        else if (follow_symlinks)
  Branch (12999:18): [True: 8.65k, False: 5]
13000
8.65k
            length = listxattr(name, buffer, buffer_size);
13001
5
        else
13002
5
            length = llistxattr(name, buffer, buffer_size);
13003
8.67k
        Py_END_ALLOW_THREADS;
Line
Count
Source
147
8.67k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
8.67k
                 }
13004
13005
8.67k
        if (length < 0) {
  Branch (13005:13): [True: 11, False: 8.65k]
13006
11
            if (errno == ERANGE) {
  Branch (13006:17): [True: 6, False: 5]
13007
6
                PyMem_Free(buffer);
13008
6
                buffer = NULL;
13009
6
                continue;
13010
6
            }
13011
5
            path_error(path);
13012
5
            break;
13013
11
        }
13014
13015
8.65k
        result = PyList_New(0);
13016
8.65k
        if (!result) {
  Branch (13016:13): [True: 0, False: 8.65k]
13017
0
            goto exit;
13018
0
        }
13019
13020
8.65k
        end = buffer + length;
13021
16.0k
        for (trace = start = buffer; trace != end; trace++) {
  Branch (13021:38): [True: 7.39k, False: 8.65k]
13022
7.39k
            if (!*trace) {
  Branch (13022:17): [True: 624, False: 6.76k]
13023
624
                int error;
13024
624
                PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
13025
624
                                                                 trace - start);
13026
624
                if (!attribute) {
  Branch (13026:21): [True: 0, False: 624]
13027
0
                    Py_DECREF(result);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
13028
0
                    result = NULL;
13029
0
                    goto exit;
13030
0
                }
13031
624
                error = PyList_Append(result, attribute);
13032
624
                Py_DECREF(attribute);
Line
Count
Source
548
624
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
624
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
624
#  define _Py_CAST(type, expr) ((type)(expr))
13033
624
                if (error) {
  Branch (13033:21): [True: 0, False: 624]
13034
0
                    Py_DECREF(result);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
13035
0
                    result = NULL;
13036
0
                    goto exit;
13037
0
                }
13038
624
                start = trace + 1;
13039
624
            }
13040
7.39k
        }
13041
8.65k
    break;
13042
8.65k
    }
13043
8.66k
exit:
13044
8.66k
    if (buffer)
  Branch (13044:9): [True: 8.66k, False: 0]
13045
8.66k
        PyMem_Free(buffer);
13046
8.66k
    return result;
13047
8.66k
}
13048
#endif /* USE_XATTRS */
13049
13050
13051
/*[clinic input]
13052
os.urandom
13053
13054
    size: Py_ssize_t
13055
    /
13056
13057
Return a bytes object containing random bytes suitable for cryptographic use.
13058
[clinic start generated code]*/
13059
13060
static PyObject *
13061
os_urandom_impl(PyObject *module, Py_ssize_t size)
13062
/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
13063
166k
{
13064
166k
    PyObject *bytes;
13065
166k
    int result;
13066
13067
166k
    if (size < 0)
  Branch (13067:9): [True: 1, False: 166k]
13068
1
        return PyErr_Format(PyExc_ValueError,
13069
1
                            "negative argument not allowed");
13070
166k
    bytes = PyBytes_FromStringAndSize(NULL, size);
13071
166k
    if (bytes == NULL)
  Branch (13071:9): [True: 0, False: 166k]
13072
0
        return NULL;
13073
13074
166k
    result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Line
Count
Source
39
166k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
166k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
166k
#  define _Py_CAST(type, expr) ((type)(expr))
    result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Line
Count
Source
45
166k
#define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self))
Line
Count
Source
109
166k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
166k
#  define _Py_CAST(type, expr) ((type)(expr))
13075
166k
    if (result == -1) {
  Branch (13075:9): [True: 0, False: 166k]
13076
0
        Py_DECREF(bytes);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
13077
0
        return NULL;
13078
0
    }
13079
166k
    return bytes;
13080
166k
}
13081
13082
#ifdef HAVE_MEMFD_CREATE
13083
/*[clinic input]
13084
os.memfd_create
13085
13086
    name: FSConverter
13087
    flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
13088
13089
[clinic start generated code]*/
13090
13091
static PyObject *
13092
os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
13093
/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
13094
2
{
13095
2
    int fd;
13096
2
    const char *bytes = PyBytes_AS_STRING(name);
Line
Count
Source
39
2
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
2
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2
#  define _Py_CAST(type, expr) ((type)(expr))
13097
2
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
2
#define Py_BEGIN_ALLOW_THREADS { \
143
2
                        PyThreadState *_save; \
144
2
                        _save = PyEval_SaveThread();
13098
2
    fd = memfd_create(bytes, flags);
13099
2
    Py_END_ALLOW_THREADS
Line
Count
Source
147
2
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
2
                 }
13100
2
    if (fd == -1) {
  Branch (13100:9): [True: 0, False: 2]
13101
0
        return PyErr_SetFromErrno(PyExc_OSError);
13102
0
    }
13103
2
    return PyLong_FromLong(fd);
13104
2
}
13105
#endif
13106
13107
#ifdef HAVE_EVENTFD
13108
/*[clinic input]
13109
os.eventfd
13110
13111
    initval: unsigned_int
13112
    flags: int(c_default="EFD_CLOEXEC") = EFD_CLOEXEC
13113
13114
Creates and returns an event notification file descriptor.
13115
[clinic start generated code]*/
13116
13117
static PyObject *
13118
os_eventfd_impl(PyObject *module, unsigned int initval, int flags)
13119
/*[clinic end generated code: output=ce9c9bbd1446f2de input=66203e3c50c4028b]*/
13120
13121
3
{
13122
    /* initval is limited to uint32_t, internal counter is uint64_t */
13123
3
    int fd;
13124
3
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
3
#define Py_BEGIN_ALLOW_THREADS { \
143
3
                        PyThreadState *_save; \
144
3
                        _save = PyEval_SaveThread();
13125
3
    fd = eventfd(initval, flags);
13126
3
    Py_END_ALLOW_THREADS
Line
Count
Source
147
3
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
3
                 }
13127
3
    if (fd == -1) {
  Branch (13127:9): [True: 0, False: 3]
13128
0
        return PyErr_SetFromErrno(PyExc_OSError);
13129
0
    }
13130
3
    return PyLong_FromLong(fd);
13131
3
}
13132
13133
/*[clinic input]
13134
os.eventfd_read
13135
13136
    fd: fildes
13137
13138
Read eventfd value
13139
[clinic start generated code]*/
13140
13141
static PyObject *
13142
os_eventfd_read_impl(PyObject *module, int fd)
13143
/*[clinic end generated code: output=8f2c7b59a3521fd1 input=110f8b57fa596afe]*/
13144
8
{
13145
8
    eventfd_t value;
13146
8
    int result;
13147
8
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
8
#define Py_BEGIN_ALLOW_THREADS { \
143
8
                        PyThreadState *_save; \
144
8
                        _save = PyEval_SaveThread();
13148
8
    result = eventfd_read(fd, &value);
13149
8
    Py_END_ALLOW_THREADS
Line
Count
Source
147
8
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
8
                 }
13150
8
    if (result == -1) {
  Branch (13150:9): [True: 2, False: 6]
13151
2
        return PyErr_SetFromErrno(PyExc_OSError);
13152
2
    }
13153
6
    return PyLong_FromUnsignedLongLong(value);
13154
8
}
13155
13156
/*[clinic input]
13157
os.eventfd_write
13158
13159
    fd: fildes
13160
    value: unsigned_long_long
13161
13162
Write eventfd value.
13163
[clinic start generated code]*/
13164
13165
static PyObject *
13166
os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value)
13167
/*[clinic end generated code: output=bebd9040bbf987f5 input=156de8555be5a949]*/
13168
5
{
13169
5
    int result;
13170
5
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
5
#define Py_BEGIN_ALLOW_THREADS { \
143
5
                        PyThreadState *_save; \
144
5
                        _save = PyEval_SaveThread();
13171
5
    result = eventfd_write(fd, value);
13172
5
    Py_END_ALLOW_THREADS
Line
Count
Source
147
5
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
5
                 }
13173
5
    if (result == -1) {
  Branch (13173:9): [True: 0, False: 5]
13174
0
        return PyErr_SetFromErrno(PyExc_OSError);
13175
0
    }
13176
5
    Py_RETURN_NONE;
Line
Count
Source
661
5
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
5
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
5
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5
#  define _Py_CAST(type, expr) ((type)(expr))
13177
5
}
13178
#endif  /* HAVE_EVENTFD */
13179
13180
/* Terminal size querying */
13181
13182
PyDoc_STRVAR(TerminalSize_docstring,
13183
    "A tuple of (columns, lines) for holding terminal window size");
13184
13185
static PyStructSequence_Field TerminalSize_fields[] = {
13186
    {"columns", "width of the terminal window in characters"},
13187
    {"lines", "height of the terminal window in characters"},
13188
    {NULL, NULL}
13189
};
13190
13191
static PyStructSequence_Desc TerminalSize_desc = {
13192
    "os.terminal_size",
13193
    TerminalSize_docstring,
13194
    TerminalSize_fields,
13195
    2,
13196
};
13197
13198
#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13199
/*[clinic input]
13200
os.get_terminal_size
13201
13202
    fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
13203
    /
13204
13205
Return the size of the terminal window as (columns, lines).
13206
13207
The optional argument fd (default standard output) specifies
13208
which file descriptor should be queried.
13209
13210
If the file descriptor is not connected to a terminal, an OSError
13211
is thrown.
13212
13213
This function will only be defined if an implementation is
13214
available for this system.
13215
13216
shutil.get_terminal_size is the high-level function which should
13217
normally be used, os.get_terminal_size is the low-level implementation.
13218
[clinic start generated code]*/
13219
13220
static PyObject *
13221
os_get_terminal_size_impl(PyObject *module, int fd)
13222
/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
13223
7.71k
{
13224
7.71k
    int columns, lines;
13225
7.71k
    PyObject *termsize;
13226
13227
    /* Under some conditions stdout may not be connected and
13228
     * fileno(stdout) may point to an invalid file descriptor. For example
13229
     * GUI apps don't have valid standard streams by default.
13230
     *
13231
     * If this happens, and the optional fd argument is not present,
13232
     * the ioctl below will fail returning EBADF. This is what we want.
13233
     */
13234
13235
7.71k
#ifdef TERMSIZE_USE_IOCTL
13236
7.71k
    {
13237
7.71k
        struct winsize w;
13238
7.71k
        if (ioctl(fd, TIOCGWINSZ, &w))
  Branch (13238:13): [True: 65, False: 7.64k]
13239
65
            return PyErr_SetFromErrno(PyExc_OSError);
13240
7.64k
        columns = w.ws_col;
13241
7.64k
        lines = w.ws_row;
13242
7.64k
    }
13243
0
#endif /* TERMSIZE_USE_IOCTL */
13244
13245
#ifdef TERMSIZE_USE_CONIO
13246
    {
13247
        DWORD nhandle;
13248
        HANDLE handle;
13249
        CONSOLE_SCREEN_BUFFER_INFO csbi;
13250
        switch (fd) {
13251
        case 0: nhandle = STD_INPUT_HANDLE;
13252
            break;
13253
        case 1: nhandle = STD_OUTPUT_HANDLE;
13254
            break;
13255
        case 2: nhandle = STD_ERROR_HANDLE;
13256
            break;
13257
        default:
13258
            return PyErr_Format(PyExc_ValueError, "bad file descriptor");
13259
        }
13260
        handle = GetStdHandle(nhandle);
13261
        if (handle == NULL)
13262
            return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
13263
        if (handle == INVALID_HANDLE_VALUE)
13264
            return PyErr_SetFromWindowsErr(0);
13265
13266
        if (!GetConsoleScreenBufferInfo(handle, &csbi))
13267
            return PyErr_SetFromWindowsErr(0);
13268
13269
        columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
13270
        lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
13271
    }
13272
#endif /* TERMSIZE_USE_CONIO */
13273
13274
0
    PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
13275
7.64k
    termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
13276
7.64k
    if (termsize == NULL)
  Branch (13276:9): [True: 0, False: 7.64k]
13277
0
        return NULL;
13278
7.64k
    PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
Line
Count
Source
38
7.64k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
7.64k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
7.64k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7.64k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
7.64k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7.64k
#  define _Py_CAST(type, expr) ((type)(expr))
13279
7.64k
    PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
Line
Count
Source
38
7.64k
#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v))
Line
Count
Source
37
7.64k
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
7.64k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7.64k
#  define _Py_CAST(type, expr) ((type)(expr))
    PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
Line
Count
Source
109
7.64k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
7.64k
#  define _Py_CAST(type, expr) ((type)(expr))
13280
7.64k
    if (PyErr_Occurred()) {
  Branch (13280:9): [True: 0, False: 7.64k]
13281
0
        Py_DECREF(termsize);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
13282
0
        return NULL;
13283
0
    }
13284
7.64k
    return termsize;
13285
7.64k
}
13286
#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
13287
13288
13289
/*[clinic input]
13290
os.cpu_count
13291
13292
Return the number of CPUs in the system; return None if indeterminable.
13293
13294
This number is not equivalent to the number of CPUs the current process can
13295
use.  The number of usable CPUs can be obtained with
13296
``len(os.sched_getaffinity(0))``
13297
[clinic start generated code]*/
13298
13299
static PyObject *
13300
os_cpu_count_impl(PyObject *module)
13301
/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
13302
93
{
13303
93
    int ncpu = 0;
13304
#ifdef MS_WINDOWS
13305
    ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
13306
#elif defined(__hpux)
13307
    ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
13308
#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
13309
93
    ncpu = sysconf(_SC_NPROCESSORS_ONLN);
13310
#elif defined(__VXWORKS__)
13311
    ncpu = _Py_popcount32(vxCpuEnabledGet());
13312
#elif defined(__DragonFly__) || \
13313
      defined(__OpenBSD__)   || \
13314
      defined(__FreeBSD__)   || \
13315
      defined(__NetBSD__)    || \
13316
      defined(__APPLE__)
13317
    int mib[2];
13318
    size_t len = sizeof(ncpu);
13319
    mib[0] = CTL_HW;
13320
    mib[1] = HW_NCPU;
13321
    if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
13322
        ncpu = 0;
13323
#endif
13324
93
    if (ncpu >= 1)
  Branch (13324:9): [True: 93, False: 0]
13325
93
        return PyLong_FromLong(ncpu);
13326
0
    else
13327
0
        Py_RETURN_NONE;
Line
Count
Source
661
0
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
0
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
13328
93
}
13329
13330
13331
/*[clinic input]
13332
os.get_inheritable -> bool
13333
13334
    fd: int
13335
    /
13336
13337
Get the close-on-exe flag of the specified file descriptor.
13338
[clinic start generated code]*/
13339
13340
static int
13341
os_get_inheritable_impl(PyObject *module, int fd)
13342
/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
13343
130
{
13344
130
    int return_value;
13345
130
    _Py_BEGIN_SUPPRESS_IPH
13346
130
    return_value = _Py_get_inheritable(fd);
13347
130
    _Py_END_SUPPRESS_IPH
13348
130
    return return_value;
13349
130
}
13350
13351
13352
/*[clinic input]
13353
os.set_inheritable
13354
    fd: int
13355
    inheritable: int
13356
    /
13357
13358
Set the inheritable flag of the specified file descriptor.
13359
[clinic start generated code]*/
13360
13361
static PyObject *
13362
os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
13363
/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
13364
35
{
13365
35
    int result;
13366
13367
35
    _Py_BEGIN_SUPPRESS_IPH
13368
35
    result = _Py_set_inheritable(fd, inheritable, NULL);
13369
35
    _Py_END_SUPPRESS_IPH
13370
35
    if (result < 0)
  Branch (13370:9): [True: 3, False: 32]
13371
3
        return NULL;
13372
35
    Py_RETURN_NONE;
Line
Count
Source
661
32
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
32
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
32
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
32
#  define _Py_CAST(type, expr) ((type)(expr))
13373
35
}
13374
13375
13376
#ifdef MS_WINDOWS
13377
/*[clinic input]
13378
os.get_handle_inheritable -> bool
13379
    handle: intptr_t
13380
    /
13381
13382
Get the close-on-exe flag of the specified file descriptor.
13383
[clinic start generated code]*/
13384
13385
static int
13386
os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
13387
/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
13388
{
13389
    DWORD flags;
13390
13391
    if (!GetHandleInformation((HANDLE)handle, &flags)) {
13392
        PyErr_SetFromWindowsErr(0);
13393
        return -1;
13394
    }
13395
13396
    return flags & HANDLE_FLAG_INHERIT;
13397
}
13398
13399
13400
/*[clinic input]
13401
os.set_handle_inheritable
13402
    handle: intptr_t
13403
    inheritable: bool
13404
    /
13405
13406
Set the inheritable flag of the specified handle.
13407
[clinic start generated code]*/
13408
13409
static PyObject *
13410
os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
13411
                               int inheritable)
13412
/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
13413
{
13414
    DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
13415
    if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
13416
        PyErr_SetFromWindowsErr(0);
13417
        return NULL;
13418
    }
13419
    Py_RETURN_NONE;
13420
}
13421
#endif /* MS_WINDOWS */
13422
13423
#ifndef MS_WINDOWS
13424
/*[clinic input]
13425
os.get_blocking -> bool
13426
    fd: int
13427
    /
13428
13429
Get the blocking mode of the file descriptor.
13430
13431
Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
13432
[clinic start generated code]*/
13433
13434
static int
13435
os_get_blocking_impl(PyObject *module, int fd)
13436
/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
13437
6
{
13438
6
    int blocking;
13439
13440
6
    _Py_BEGIN_SUPPRESS_IPH
13441
6
    blocking = _Py_get_blocking(fd);
13442
6
    _Py_END_SUPPRESS_IPH
13443
6
    return blocking;
13444
6
}
13445
13446
/*[clinic input]
13447
os.set_blocking
13448
    fd: int
13449
    blocking: bool(accept={int})
13450
    /
13451
13452
Set the blocking mode of the specified file descriptor.
13453
13454
Set the O_NONBLOCK flag if blocking is False,
13455
clear the O_NONBLOCK flag otherwise.
13456
[clinic start generated code]*/
13457
13458
static PyObject *
13459
os_set_blocking_impl(PyObject *module, int fd, int blocking)
13460
/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
13461
252
{
13462
252
    int result;
13463
13464
252
    _Py_BEGIN_SUPPRESS_IPH
13465
252
    result = _Py_set_blocking(fd, blocking);
13466
252
    _Py_END_SUPPRESS_IPH
13467
252
    if (result < 0)
  Branch (13467:9): [True: 1, False: 251]
13468
1
        return NULL;
13469
252
    Py_RETURN_NONE;
Line
Count
Source
661
251
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
251
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
251
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
251
#  define _Py_CAST(type, expr) ((type)(expr))
13470
252
}
13471
#endif   /* !MS_WINDOWS */
13472
13473
13474
/*[clinic input]
13475
class os.DirEntry "DirEntry *" "DirEntryType"
13476
[clinic start generated code]*/
13477
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
13478
13479
typedef struct {
13480
    PyObject_HEAD
13481
    PyObject *name;
13482
    PyObject *path;
13483
    PyObject *stat;
13484
    PyObject *lstat;
13485
#ifdef MS_WINDOWS
13486
    struct _Py_stat_struct win32_lstat;
13487
    uint64_t win32_file_index;
13488
    int got_file_index;
13489
#else /* POSIX */
13490
#ifdef HAVE_DIRENT_D_TYPE
13491
    unsigned char d_type;
13492
#endif
13493
    ino_t d_ino;
13494
    int dir_fd;
13495
#endif
13496
} DirEntry;
13497
13498
static void
13499
DirEntry_dealloc(DirEntry *entry)
13500
105k
{
13501
105k
    PyTypeObject *tp = Py_TYPE(entry);
Line
Count
Source
138
105k
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
105k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
105k
#  define _Py_CAST(type, expr) ((type)(expr))
13502
105k
    Py_XDECREF(entry->name);
Line
Count
Source
613
105k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
105k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
105k
#  define _Py_CAST(type, expr) ((type)(expr))
13503
105k
    Py_XDECREF(entry->path);
Line
Count
Source
613
105k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
105k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
105k
#  define _Py_CAST(type, expr) ((type)(expr))
13504
105k
    Py_XDECREF(entry->stat);
Line
Count
Source
613
105k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
105k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
105k
#  define _Py_CAST(type, expr) ((type)(expr))
13505
105k
    Py_XDECREF(entry->lstat);
Line
Count
Source
613
105k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
105k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
105k
#  define _Py_CAST(type, expr) ((type)(expr))
13506
105k
    freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
Line
Count
Source
75
105k
#define Py_tp_free 74
13507
105k
    free_func(entry);
13508
105k
    Py_DECREF(tp);
Line
Count
Source
548
105k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
105k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
105k
#  define _Py_CAST(type, expr) ((type)(expr))
13509
105k
}
13510
13511
/* Forward reference */
13512
static int
13513
DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13514
                   int follow_symlinks, unsigned short mode_bits);
13515
13516
/*[clinic input]
13517
os.DirEntry.is_symlink -> bool
13518
    defining_class: defining_class
13519
    /
13520
13521
Return True if the entry is a symbolic link; cached per entry.
13522
[clinic start generated code]*/
13523
13524
static int
13525
os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
13526
/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
13527
33.7k
{
13528
#ifdef MS_WINDOWS
13529
    return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
13530
#elif defined(HAVE_DIRENT_D_TYPE)
13531
    /* POSIX */
13532
33.7k
    if (self->d_type != DT_UNKNOWN)
  Branch (13532:9): [True: 33.7k, False: 0]
13533
33.7k
        return self->d_type == DT_LNK;
13534
0
    else
13535
0
        return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
13536
#else
13537
    /* POSIX without d_type */
13538
    return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
13539
#endif
13540
33.7k
}
13541
13542
static PyObject *
13543
DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
13544
17.1k
{
13545
17.1k
    int result;
13546
17.1k
    STRUCT_STAT st;
Line
Count
Source
473
17.1k
#  define STRUCT_STAT struct stat
13547
17.1k
    PyObject *ub;
13548
13549
#ifdef MS_WINDOWS
13550
    if (!PyUnicode_FSDecoder(self->path, &ub))
13551
        return NULL;
13552
    wchar_t *path = PyUnicode_AsWideCharString(ub, NULL);
13553
    Py_DECREF(ub);
13554
#else /* POSIX */
13555
17.1k
    if (!PyUnicode_FSConverter(self->path, &ub))
  Branch (13555:9): [True: 0, False: 17.1k]
13556
0
        return NULL;
13557
17.1k
    const char *path = PyBytes_AS_STRING(ub);
Line
Count
Source
39
17.1k
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
17.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
17.1k
#  define _Py_CAST(type, expr) ((type)(expr))
13558
17.1k
    if (self->dir_fd != DEFAULT_DIR_FD) {
Line
Count
Source
904
17.1k
#define DEFAULT_DIR_FD (int)AT_FDCWD
  Branch (13558:9): [True: 7.75k, False: 9.39k]
13559
7.75k
#ifdef HAVE_FSTATAT
13560
7.75k
      if (HAVE_FSTATAT_RUNTIME) {
Line
Count
Source
163
7.75k
#  define HAVE_FSTATAT_RUNTIME 1
  Branch (163:32): [Folded - Ignored]
13561
7.75k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
7.75k
#define Py_BEGIN_ALLOW_THREADS { \
143
7.75k
                        PyThreadState *_save; \
144
7.75k
                        _save = PyEval_SaveThread();
13562
7.75k
        result = fstatat(self->dir_fd, path, &st,
13563
7.75k
                         follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
  Branch (13563:26): [True: 2.32k, False: 5.42k]
13564
7.75k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
7.75k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
7.75k
                 }
13565
7.75k
      } else
13566
13567
0
#endif /* HAVE_FSTATAT */
13568
0
      {
13569
0
        Py_DECREF(ub);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
13570
0
        PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
13571
0
        return NULL;
13572
0
      }
13573
7.75k
    }
13574
9.39k
    else
13575
9.39k
#endif
13576
9.39k
    {
13577
9.39k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
9.39k
#define Py_BEGIN_ALLOW_THREADS { \
143
9.39k
                        PyThreadState *_save; \
144
9.39k
                        _save = PyEval_SaveThread();
13578
9.39k
        if (follow_symlinks) {
  Branch (13578:13): [True: 794, False: 8.59k]
13579
794
            result = STAT(path, &st);
Line
Count
Source
470
794
#  define STAT stat
13580
794
        }
13581
8.59k
        else {
13582
8.59k
            result = LSTAT(path, &st);
Line
Count
Source
471
8.59k
#  define LSTAT lstat
13583
8.59k
        }
13584
9.39k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
9.39k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
9.39k
                 }
13585
9.39k
    }
13586
#if defined(MS_WINDOWS)
13587
    PyMem_Free(path);
13588
#else
13589
17.1k
    Py_DECREF(ub);
Line
Count
Source
548
17.1k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
17.1k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
17.1k
#  define _Py_CAST(type, expr) ((type)(expr))
13590
17.1k
#endif
13591
13592
17.1k
    if (result != 0)
  Branch (13592:9): [True: 2.18k, False: 14.9k]
13593
2.18k
        return path_object_error(self->path);
13594
13595
14.9k
    return _pystat_fromstructstat(module, &st);
13596
17.1k
}
13597
13598
static PyObject *
13599
DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
13600
14.0k
{
13601
14.0k
    if (!self->lstat) {
  Branch (13601:9): [True: 14.0k, False: 4]
13602
14.0k
        PyObject *module = PyType_GetModule(defining_class);
13603
#ifdef MS_WINDOWS
13604
        self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
13605
#else /* POSIX */
13606
14.0k
        self->lstat = DirEntry_fetch_stat(module, self, 0);
13607
14.0k
#endif
13608
14.0k
    }
13609
14.0k
    Py_XINCREF(self->lstat);
Line
Count
Source
603
14.0k
#  define Py_XINCREF(op) Py_XINCREF(_PyObject_CAST(op))
Line
Count
Source
109
14.0k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
14.0k
#  define _Py_CAST(type, expr) ((type)(expr))
13610
14.0k
    return self->lstat;
13611
14.0k
}
13612
13613
/*[clinic input]
13614
os.DirEntry.stat
13615
    defining_class: defining_class
13616
    /
13617
    *
13618
    follow_symlinks: bool = True
13619
13620
Return stat_result object for the entry; cached per entry.
13621
[clinic start generated code]*/
13622
13623
static PyObject *
13624
os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
13625
                      int follow_symlinks)
13626
/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
13627
32.9k
{
13628
32.9k
    if (!follow_symlinks) {
  Branch (13628:9): [True: 5.43k, False: 27.5k]
13629
5.43k
        return DirEntry_get_lstat(defining_class, self);
13630
5.43k
    }
13631
13632
27.5k
    if (!self->stat) {
  Branch (13632:9): [True: 11.7k, False: 15.8k]
13633
11.7k
        int result = os_DirEntry_is_symlink_impl(self, defining_class);
13634
11.7k
        if (result == -1) {
  Branch (13634:13): [True: 0, False: 11.7k]
13635
0
            return NULL;
13636
0
        }
13637
11.7k
        if (result) {
  Branch (13637:13): [True: 3.11k, False: 8.59k]
13638
3.11k
            PyObject *module = PyType_GetModule(defining_class);
13639
3.11k
            self->stat = DirEntry_fetch_stat(module, self, 1);
13640
3.11k
        }
13641
8.59k
        else {
13642
8.59k
            self->stat = DirEntry_get_lstat(defining_class, self);
13643
8.59k
        }
13644
11.7k
    }
13645
13646
27.5k
    Py_XINCREF(self->stat);
Line
Count
Source
603
27.5k
#  define Py_XINCREF(op) Py_XINCREF(_PyObject_CAST(op))
Line
Count
Source
109
27.5k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
27.5k
#  define _Py_CAST(type, expr) ((type)(expr))
13647
27.5k
    return self->stat;
13648
27.5k
}
13649
13650
/* Set exception and return -1 on error, 0 for False, 1 for True */
13651
static int
13652
DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13653
                   int follow_symlinks, unsigned short mode_bits)
13654
92.3k
{
13655
92.3k
    PyObject *stat = NULL;
13656
92.3k
    PyObject *st_mode = NULL;
13657
92.3k
    long mode;
13658
92.3k
    int result;
13659
92.3k
#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
13660
92.3k
    int is_symlink;
13661
92.3k
    int need_stat;
13662
92.3k
#endif
13663
#ifdef MS_WINDOWS
13664
    unsigned long dir_bits;
13665
#endif
13666
13667
#ifdef MS_WINDOWS
13668
    is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
13669
    need_stat = follow_symlinks && is_symlink;
13670
#elif defined(HAVE_DIRENT_D_TYPE)
13671
92.3k
    is_symlink = self->d_type == DT_LNK;
13672
92.3k
    need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
  Branch (13672:17): [True: 0, False: 92.3k]
  Branch (13672:48): [True: 57.9k, False: 34.3k]
  Branch (13672:67): [True: 3.11k, False: 54.8k]
13673
92.3k
#endif
13674
13675
92.3k
#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
13676
92.3k
    if (need_stat) {
  Branch (13676:9): [True: 3.11k, False: 89.2k]
13677
3.11k
#endif
13678
3.11k
        stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
13679
3.11k
        if (!stat) {
  Branch (13679:13): [True: 2.16k, False: 951]
13680
2.16k
            if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
  Branch (13680:17): [True: 982, False: 1.18k]
13681
                /* If file doesn't exist (anymore), then return False
13682
                   (i.e., say it's not a file/directory) */
13683
982
                PyErr_Clear();
13684
982
                return 0;
13685
982
            }
13686
1.18k
            goto error;
13687
2.16k
        }
13688
951
        _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
13689
951
        st_mode = PyObject_GetAttr(stat, state->st_mode);
13690
951
        if (!st_mode)
  Branch (13690:13): [True: 0, False: 951]
13691
0
            goto error;
13692
13693
951
        mode = PyLong_AsLong(st_mode);
13694
951
        if (mode == -1 && PyErr_Occurred())
  Branch (13694:13): [True: 0, False: 951]
  Branch (13694:27): [True: 0, False: 0]
13695
0
            goto error;
13696
951
        Py_CLEAR(st_mode);
Line
Count
Source
587
951
    do {                                        \
588
951
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
951
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
951
#  define _Py_CAST(type, expr) ((type)(expr))
589
951
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 951, False: 0]
590
951
            (op) = NULL;                        \
591
951
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
951
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
951
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
951
#  define _Py_CAST(type, expr) ((type)(expr))
592
951
        }                                       \
593
951
    } while (0)
  Branch (593:14): [Folded - Ignored]
13697
951
        Py_CLEAR(stat);
Line
Count
Source
587
951
    do {                                        \
588
951
        PyObject *_py_tmp = _PyObject_CAST(op); \
Line
Count
Source
109
951
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
951
#  define _Py_CAST(type, expr) ((type)(expr))
589
951
        if (_py_tmp != NULL) {                  \
  Branch (589:13): [True: 951, False: 0]
590
951
            (op) = NULL;                        \
591
951
            Py_DECREF(_py_tmp);                 \
Line
Count
Source
548
951
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
951
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
951
#  define _Py_CAST(type, expr) ((type)(expr))
592
951
        }                                       \
593
951
    } while (0)
  Branch (593:14): [Folded - Ignored]
13698
951
        result = (mode & S_IFMT) == mode_bits;
13699
951
#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
13700
951
    }
13701
89.2k
    else if (is_symlink) {
  Branch (13701:14): [True: 1.19k, False: 88.0k]
13702
1.19k
        assert(mode_bits != S_IFLNK);
13703
1.19k
        result = 0;
13704
1.19k
    }
13705
88.0k
    else {
13706
88.0k
        assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
13707
#ifdef MS_WINDOWS
13708
        dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
13709
        if (mode_bits == S_IFDIR)
13710
            result = dir_bits != 0;
13711
        else
13712
            result = dir_bits == 0;
13713
#else /* POSIX */
13714
88.0k
        if (mode_bits == S_IFDIR)
  Branch (13714:13): [True: 88.0k, False: 7]
13715
88.0k
            result = self->d_type == DT_DIR;
13716
7
        else
13717
7
            result = self->d_type == DT_REG;
13718
88.0k
#endif
13719
88.0k
    }
13720
90.2k
#endif
13721
13722
90.2k
    return result;
13723
13724
1.18k
error:
13725
1.18k
    Py_XDECREF(st_mode);
Line
Count
Source
613
1.18k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
1.18k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1.18k
#  define _Py_CAST(type, expr) ((type)(expr))
13726
1.18k
    Py_XDECREF(stat);
Line
Count
Source
613
1.18k
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
1.18k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
1.18k
#  define _Py_CAST(type, expr) ((type)(expr))
13727
1.18k
    return -1;
13728
92.3k
}
13729
13730
/*[clinic input]
13731
os.DirEntry.is_dir -> bool
13732
    defining_class: defining_class
13733
    /
13734
    *
13735
    follow_symlinks: bool = True
13736
13737
Return True if the entry is a directory; cached per entry.
13738
[clinic start generated code]*/
13739
13740
static int
13741
os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
13742
                        int follow_symlinks)
13743
/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
13744
92.3k
{
13745
92.3k
    return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
13746
92.3k
}
13747
13748
/*[clinic input]
13749
os.DirEntry.is_file -> bool
13750
    defining_class: defining_class
13751
    /
13752
    *
13753
    follow_symlinks: bool = True
13754
13755
Return True if the entry is a file; cached per entry.
13756
[clinic start generated code]*/
13757
13758
static int
13759
os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13760
                         int follow_symlinks)
13761
/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
13762
13
{
13763
13
    return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
13764
13
}
13765
13766
/*[clinic input]
13767
os.DirEntry.inode
13768
13769
Return inode of the entry; cached per entry.
13770
[clinic start generated code]*/
13771
13772
static PyObject *
13773
os_DirEntry_inode_impl(DirEntry *self)
13774
/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
13775
8
{
13776
#ifdef MS_WINDOWS
13777
    if (!self->got_file_index) {
13778
        PyObject *unicode;
13779
        STRUCT_STAT stat;
13780
        int result;
13781
13782
        if (!PyUnicode_FSDecoder(self->path, &unicode))
13783
            return NULL;
13784
        wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL);
13785
        Py_DECREF(unicode);
13786
        result = LSTAT(path, &stat);
13787
        PyMem_Free(path);
13788
13789
        if (result != 0)
13790
            return path_object_error(self->path);
13791
13792
        self->win32_file_index = stat.st_ino;
13793
        self->got_file_index = 1;
13794
    }
13795
    static_assert(sizeof(unsigned long long) >= sizeof(self->win32_file_index),
13796
                  "DirEntry.win32_file_index is larger than unsigned long long");
13797
    return PyLong_FromUnsignedLongLong(self->win32_file_index);
13798
#else /* POSIX */
13799
8
    static_assert(sizeof(unsigned long long) >= sizeof(self->d_ino),
13800
8
                  "DirEntry.d_ino is larger than unsigned long long");
13801
8
    return PyLong_FromUnsignedLongLong(self->d_ino);
13802
8
#endif
13803
8
}
13804
13805
static PyObject *
13806
DirEntry_repr(DirEntry *self)
13807
1
{
13808
1
    return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13809
1
}
13810
13811
/*[clinic input]
13812
os.DirEntry.__fspath__
13813
13814
Returns the path for the entry.
13815
[clinic start generated code]*/
13816
13817
static PyObject *
13818
os_DirEntry___fspath___impl(DirEntry *self)
13819
/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
13820
25.6k
{
13821
25.6k
    Py_INCREF(self->path);
Line
Count
Source
512
25.6k
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
25.6k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
25.6k
#  define _Py_CAST(type, expr) ((type)(expr))
13822
25.6k
    return self->path;
13823
25.6k
}
13824
13825
static PyMemberDef DirEntry_members[] = {
13826
    {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13827
     "the entry's base filename, relative to scandir() \"path\" argument"},
13828
    {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13829
     "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13830
    {NULL}
13831
};
13832
13833
#include "clinic/posixmodule.c.h"
13834
13835
static PyMethodDef DirEntry_methods[] = {
13836
    OS_DIRENTRY_IS_DIR_METHODDEF
13837
    OS_DIRENTRY_IS_FILE_METHODDEF
13838
    OS_DIRENTRY_IS_SYMLINK_METHODDEF
13839
    OS_DIRENTRY_STAT_METHODDEF
13840
    OS_DIRENTRY_INODE_METHODDEF
13841
    OS_DIRENTRY___FSPATH___METHODDEF
13842
    {"__class_getitem__",       Py_GenericAlias,
13843
    METH_O|METH_CLASS,          PyDoc_STR("See PEP 585")},
13844
    {NULL}
13845
};
13846
13847
static PyType_Slot DirEntryType_slots[] = {
13848
    {Py_tp_dealloc, DirEntry_dealloc},
13849
    {Py_tp_repr, DirEntry_repr},
13850
    {Py_tp_methods, DirEntry_methods},
13851
    {Py_tp_members, DirEntry_members},
13852
    {0, 0},
13853
};
13854
13855
static PyType_Spec DirEntryType_spec = {
13856
    MODNAME ".DirEntry",
13857
    sizeof(DirEntry),
13858
    0,
13859
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
13860
    DirEntryType_slots
13861
};
13862
13863
13864
#ifdef MS_WINDOWS
13865
13866
static wchar_t *
13867
join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
13868
{
13869
    Py_ssize_t path_len;
13870
    Py_ssize_t size;
13871
    wchar_t *result;
13872
    wchar_t ch;
13873
13874
    if (!path_wide) { /* Default arg: "." */
13875
        path_wide = L".";
13876
        path_len = 1;
13877
    }
13878
    else {
13879
        path_len = wcslen(path_wide);
13880
    }
13881
13882
    /* The +1's are for the path separator and the NUL */
13883
    size = path_len + 1 + wcslen(filename) + 1;
13884
    result = PyMem_New(wchar_t, size);
13885
    if (!result) {
13886
        PyErr_NoMemory();
13887
        return NULL;
13888
    }
13889
    wcscpy(result, path_wide);
13890
    if (path_len > 0) {
13891
        ch = result[path_len - 1];
13892
        if (ch != SEP && ch != ALTSEP && ch != L':')
13893
            result[path_len++] = SEP;
13894
        wcscpy(result + path_len, filename);
13895
    }
13896
    return result;
13897
}
13898
13899
static PyObject *
13900
DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
13901
{
13902
    DirEntry *entry;
13903
    BY_HANDLE_FILE_INFORMATION file_info;
13904
    ULONG reparse_tag;
13905
    wchar_t *joined_path;
13906
13907
    PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
13908
    entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
13909
    if (!entry)
13910
        return NULL;
13911
    entry->name = NULL;
13912
    entry->path = NULL;
13913
    entry->stat = NULL;
13914
    entry->lstat = NULL;
13915
    entry->got_file_index = 0;
13916
13917
    entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13918
    if (!entry->name)
13919
        goto error;
13920
    if (path->narrow) {
13921
        Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13922
        if (!entry->name)
13923
            goto error;
13924
    }
13925
13926
    joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13927
    if (!joined_path)
13928
        goto error;
13929
13930
    entry->path = PyUnicode_FromWideChar(joined_path, -1);
13931
    PyMem_Free(joined_path);
13932
    if (!entry->path)
13933
        goto error;
13934
    if (path->narrow) {
13935
        Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13936
        if (!entry->path)
13937
            goto error;
13938
    }
13939
13940
    find_data_to_file_info(dataW, &file_info, &reparse_tag);
13941
    _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13942
13943
    return (PyObject *)entry;
13944
13945
error:
13946
    Py_DECREF(entry);
13947
    return NULL;
13948
}
13949
13950
#else /* POSIX */
13951
13952
static char *
13953
join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
13954
61.8k
{
13955
61.8k
    Py_ssize_t path_len;
13956
61.8k
    Py_ssize_t size;
13957
61.8k
    char *result;
13958
13959
61.8k
    if (!path_narrow) { /* Default arg: "." */
  Branch (13959:9): [True: 1, False: 61.8k]
13960
1
        path_narrow = ".";
13961
1
        path_len = 1;
13962
1
    }
13963
61.8k
    else {
13964
61.8k
        path_len = strlen(path_narrow);
13965
61.8k
    }
13966
13967
61.8k
    if (filename_len == -1)
  Branch (13967:9): [True: 0, False: 61.8k]
13968
0
        filename_len = strlen(filename);
13969
13970
    /* The +1's are for the path separator and the NUL */
13971
61.8k
    size = path_len + 1 + filename_len + 1;
13972
61.8k
    result = PyMem_New(char, size);
Line
Count
Source
68
61.8k
  ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL :      \
Line
Count
Source
180
61.8k
#   define PY_SSIZE_T_MAX SSIZE_MAX
  Branch (68:5): [True: 0, False: 61.8k]
69
61.8k
        ( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
13973
61.8k
    if (!result) {
  Branch (13973:9): [True: 0, False: 61.8k]
13974
0
        PyErr_NoMemory();
13975
0
        return NULL;
13976
0
    }
13977
61.8k
    strcpy(result, path_narrow);
13978
61.8k
    if (path_len > 0 && result[path_len - 1] != '/')
  Branch (13978:9): [True: 61.8k, False: 0]
  Branch (13978:25): [True: 61.7k, False: 90]
13979
61.7k
        result[path_len++] = '/';
13980
61.8k
    strcpy(result + path_len, filename);
13981
61.8k
    return result;
13982
61.8k
}
13983
13984
static PyObject *
13985
DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13986
                         Py_ssize_t name_len, ino_t d_ino
13987
#ifdef HAVE_DIRENT_D_TYPE
13988
                         , unsigned char d_type
13989
#endif
13990
                         )
13991
105k
{
13992
105k
    DirEntry *entry;
13993
105k
    char *joined_path;
13994
13995
105k
    PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
13996
105k
    entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Line
Count
Source
134
105k
#define PyObject_New(type, typeobj) ((type *)_PyObject_New(typeobj))
13997
105k
    if (!entry)
  Branch (13997:9): [True: 0, False: 105k]
13998
0
        return NULL;
13999
105k
    entry->name = NULL;
14000
105k
    entry->path = NULL;
14001
105k
    entry->stat = NULL;
14002
105k
    entry->lstat = NULL;
14003
14004
105k
    if (path->fd != -1) {
  Branch (14004:9): [True: 43.5k, False: 61.8k]
14005
43.5k
        entry->dir_fd = path->fd;
14006
43.5k
        joined_path = NULL;
14007
43.5k
    }
14008
61.8k
    else {
14009
61.8k
        entry->dir_fd = DEFAULT_DIR_FD;
Line
Count
Source
904
61.8k
#define DEFAULT_DIR_FD (int)AT_FDCWD
14010
61.8k
        joined_path = join_path_filename(path->narrow, name, name_len);
14011
61.8k
        if (!joined_path)
  Branch (14011:13): [True: 0, False: 61.8k]
14012
0
            goto error;
14013
61.8k
    }
14014
14015
105k
    if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
  Branch (14015:9): [True: 43.5k, False: 61.8k]
  Branch (14015:26): [True: 53.4k, False: 8.42k]
14016
96.9k
        entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
14017
96.9k
        if (joined_path)
  Branch (14017:13): [True: 53.4k, False: 43.5k]
14018
53.4k
            entry->path = PyUnicode_DecodeFSDefault(joined_path);
14019
96.9k
    }
14020
8.42k
    else {
14021
8.42k
        entry->name = PyBytes_FromStringAndSize(name, name_len);
14022
8.42k
        if (joined_path)
  Branch (14022:13): [True: 8.42k, False: 0]
14023
8.42k
            entry->path = PyBytes_FromString(joined_path);
14024
8.42k
    }
14025
105k
    PyMem_Free(joined_path);
14026
105k
    if (!entry->name)
  Branch (14026:9): [True: 0, False: 105k]
14027
0
        goto error;
14028
14029
105k
    if (path->fd != -1) {
  Branch (14029:9): [True: 43.5k, False: 61.8k]
14030
43.5k
        entry->path = entry->name;
14031
43.5k
        Py_INCREF(entry->path);
Line
Count
Source
512
43.5k
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
43.5k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
43.5k
#  define _Py_CAST(type, expr) ((type)(expr))
14032
43.5k
    }
14033
61.8k
    else if (!entry->path)
  Branch (14033:14): [True: 0, False: 61.8k]
14034
0
        goto error;
14035
14036
105k
#ifdef HAVE_DIRENT_D_TYPE
14037
105k
    entry->d_type = d_type;
14038
105k
#endif
14039
105k
    entry->d_ino = d_ino;
14040
14041
105k
    return (PyObject *)entry;
14042
14043
0
error:
14044
0
    Py_XDECREF(entry);
Line
Count
Source
613
0
#  define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
14045
0
    return NULL;
14046
105k
}
14047
14048
#endif
14049
14050
14051
typedef struct {
14052
    PyObject_HEAD
14053
    path_t path;
14054
#ifdef MS_WINDOWS
14055
    HANDLE handle;
14056
    WIN32_FIND_DATAW file_data;
14057
    int first_time;
14058
#else /* POSIX */
14059
    DIR *dirp;
14060
#endif
14061
#ifdef HAVE_FDOPENDIR
14062
    int fd;
14063
#endif
14064
} ScandirIterator;
14065
14066
#ifdef MS_WINDOWS
14067
14068
static int
14069
ScandirIterator_is_closed(ScandirIterator *iterator)
14070
{
14071
    return iterator->handle == INVALID_HANDLE_VALUE;
14072
}
14073
14074
static void
14075
ScandirIterator_closedir(ScandirIterator *iterator)
14076
{
14077
    HANDLE handle = iterator->handle;
14078
14079
    if (handle == INVALID_HANDLE_VALUE)
14080
        return;
14081
14082
    iterator->handle = INVALID_HANDLE_VALUE;
14083
    Py_BEGIN_ALLOW_THREADS
14084
    FindClose(handle);
14085
    Py_END_ALLOW_THREADS
14086
}
14087
14088
static PyObject *
14089
ScandirIterator_iternext(ScandirIterator *iterator)
14090
{
14091
    WIN32_FIND_DATAW *file_data = &iterator->file_data;
14092
    BOOL success;
14093
    PyObject *entry;
14094
14095
    /* Happens if the iterator is iterated twice, or closed explicitly */
14096
    if (iterator->handle == INVALID_HANDLE_VALUE)
14097
        return NULL;
14098
14099
    while (1) {
14100
        if (!iterator->first_time) {
14101
            Py_BEGIN_ALLOW_THREADS
14102
            success = FindNextFileW(iterator->handle, file_data);
14103
            Py_END_ALLOW_THREADS
14104
            if (!success) {
14105
                /* Error or no more files */
14106
                if (GetLastError() != ERROR_NO_MORE_FILES)
14107
                    path_error(&iterator->path);
14108
                break;
14109
            }
14110
        }
14111
        iterator->first_time = 0;
14112
14113
        /* Skip over . and .. */
14114
        if (wcscmp(file_data->cFileName, L".") != 0 &&
14115
            wcscmp(file_data->cFileName, L"..") != 0)
14116
        {
14117
            PyObject *module = PyType_GetModule(Py_TYPE(iterator));
14118
            entry = DirEntry_from_find_data(module, &iterator->path, file_data);
14119
            if (!entry)
14120
                break;
14121
            return entry;
14122
        }
14123
14124
        /* Loop till we get a non-dot directory or finish iterating */
14125
    }
14126
14127
    /* Error or no more files */
14128
    ScandirIterator_closedir(iterator);
14129
    return NULL;
14130
}
14131
14132
#else /* POSIX */
14133
14134
static int
14135
ScandirIterator_is_closed(ScandirIterator *iterator)
14136
46.2k
{
14137
46.2k
    return !iterator->dirp;
14138
46.2k
}
14139
14140
static void
14141
ScandirIterator_closedir(ScandirIterator *iterator)
14142
88.2k
{
14143
88.2k
    DIR *dirp = iterator->dirp;
14144
14145
88.2k
    if (!dirp)
  Branch (14145:9): [True: 42.5k, False: 45.7k]
14146
42.5k
        return;
14147
14148
45.7k
    iterator->dirp = NULL;
14149
45.7k
    Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
45.7k
#define Py_BEGIN_ALLOW_THREADS { \
143
45.7k
                        PyThreadState *_save; \
144
45.7k
                        _save = PyEval_SaveThread();
14150
45.7k
#ifdef HAVE_FDOPENDIR
14151
45.7k
    if (iterator->path.fd != -1)
  Branch (14151:9): [True: 11.6k, False: 34.1k]
14152
11.6k
        rewinddir(dirp);
14153
45.7k
#endif
14154
45.7k
    closedir(dirp);
14155
45.7k
    Py_END_ALLOW_THREADS
Line
Count
Source
147
45.7k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
45.7k
                 }
14156
45.7k
    return;
14157
88.2k
}
14158
14159
static PyObject *
14160
ScandirIterator_iternext(ScandirIterator *iterator)
14161
151k
{
14162
151k
    struct dirent *direntp;
14163
151k
    Py_ssize_t name_len;
14164
151k
    int is_dot;
14165
151k
    PyObject *entry;
14166
14167
    /* Happens if the iterator is iterated twice, or closed explicitly */
14168
151k
    if (!iterator->dirp)
  Branch (14168:9): [True: 1, False: 151k]
14169
1
        return NULL;
14170
14171
242k
    while (1) {
  Branch (14171:12): [Folded - Ignored]
14172
242k
        errno = 0;
14173
242k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
242k
#define Py_BEGIN_ALLOW_THREADS { \
143
242k
                        PyThreadState *_save; \
144
242k
                        _save = PyEval_SaveThread();
14174
242k
        direntp = readdir(iterator->dirp);
14175
242k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
242k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
242k
                 }
14176
14177
242k
        if (!direntp) {
  Branch (14177:13): [True: 45.7k, False: 196k]
14178
            /* Error or no more files */
14179
45.7k
            if (errno != 0)
  Branch (14179:17): [True: 0, False: 45.7k]
14180
0
                path_error(&iterator->path);
14181
45.7k
            break;
14182
45.7k
        }
14183
14184
        /* Skip over . and .. */
14185
196k
        name_len = NAMLEN(direntp);
Line
Count
Source
383
196k
#  define NAMLEN(dirent) strlen((dirent)->d_name)
14186
196k
        is_dot = direntp->d_name[0] == '.' &&
  Branch (14186:18): [True: 92.5k, False: 104k]
14187
196k
                 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
  Branch (14187:19): [True: 45.7k, False: 46.7k]
  Branch (14187:37): [True: 45.7k, False: 994]
  Branch (14187:66): [True: 45.7k, False: 4]
14188
196k
        if (!is_dot) {
  Branch (14188:13): [True: 105k, False: 91.5k]
14189
105k
            PyObject *module = PyType_GetModule(Py_TYPE(iterator));
Line
Count
Source
138
105k
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
105k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
105k
#  define _Py_CAST(type, expr) ((type)(expr))
14190
105k
            entry = DirEntry_from_posix_info(module,
14191
105k
                                             &iterator->path, direntp->d_name,
14192
105k
                                             name_len, direntp->d_ino
14193
105k
#ifdef HAVE_DIRENT_D_TYPE
14194
105k
                                             , direntp->d_type
14195
105k
#endif
14196
105k
                                            );
14197
105k
            if (!entry)
  Branch (14197:17): [True: 0, False: 105k]
14198
0
                break;
14199
105k
            return entry;
14200
105k
        }
14201
14202
        /* Loop till we get a non-dot directory or finish iterating */
14203
196k
    }
14204
14205
    /* Error or no more files */
14206
45.7k
    ScandirIterator_closedir(iterator);
14207
45.7k
    return NULL;
14208
151k
}
14209
14210
#endif
14211
14212
static PyObject *
14213
ScandirIterator_close(ScandirIterator *self, PyObject *args)
14214
5
{
14215
5
    ScandirIterator_closedir(self);
14216
5
    Py_RETURN_NONE;
Line
Count
Source
661
5
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
5
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
5
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5
#  define _Py_CAST(type, expr) ((type)(expr))
14217
5
}
14218
14219
static PyObject *
14220
ScandirIterator_enter(PyObject *self, PyObject *args)
14221
42.5k
{
14222
42.5k
    Py_INCREF(self);
Line
Count
Source
512
42.5k
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
42.5k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
42.5k
#  define _Py_CAST(type, expr) ((type)(expr))
14223
42.5k
    return self;
14224
42.5k
}
14225
14226
static PyObject *
14227
ScandirIterator_exit(ScandirIterator *self, PyObject *args)
14228
42.5k
{
14229
42.5k
    ScandirIterator_closedir(self);
14230
42.5k
    Py_RETURN_NONE;
Line
Count
Source
661
42.5k
#define Py_RETURN_NONE return Py_NewRef(Py_None)
Line
Count
Source
639
42.5k
#  define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
Line
Count
Source
109
42.5k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
42.5k
#  define _Py_CAST(type, expr) ((type)(expr))
14231
42.5k
}
14232
14233
static void
14234
ScandirIterator_finalize(ScandirIterator *iterator)
14235
46.2k
{
14236
46.2k
    PyObject *error_type, *error_value, *error_traceback;
14237
14238
    /* Save the current exception, if any. */
14239
46.2k
    PyErr_Fetch(&error_type, &error_value, &error_traceback);
14240
14241
46.2k
    if (!ScandirIterator_is_closed(iterator)) {
  Branch (14241:9): [True: 1, False: 46.2k]
14242
1
        ScandirIterator_closedir(iterator);
14243
14244
1
        if (PyErr_ResourceWarning((PyObject *)iterator, 1,
  Branch (14244:13): [True: 0, False: 1]
14245
1
                                  "unclosed scandir iterator %R", iterator)) {
14246
            /* Spurious errors can appear at shutdown */
14247
0
            if (PyErr_ExceptionMatches(PyExc_Warning)) {
  Branch (14247:17): [True: 0, False: 0]
14248
0
                PyErr_WriteUnraisable((PyObject *) iterator);
14249
0
            }
14250
0
        }
14251
1
    }
14252
14253
46.2k
    path_cleanup(&iterator->path);
14254
14255
    /* Restore the saved exception. */
14256
46.2k
    PyErr_Restore(error_type, error_value, error_traceback);
14257
46.2k
}
14258
14259
static void
14260
ScandirIterator_dealloc(ScandirIterator *iterator)
14261
46.2k
{
14262
46.2k
    PyTypeObject *tp = Py_TYPE(iterator);
Line
Count
Source
138
46.2k
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
46.2k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
46.2k
#  define _Py_CAST(type, expr) ((type)(expr))
14263
46.2k
    if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
  Branch (14263:9): [True: 1, False: 46.2k]
14264
1
        return;
14265
14266
46.2k
    freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
Line
Count
Source
75
46.2k
#define Py_tp_free 74
14267
46.2k
    free_func(iterator);
14268
46.2k
    Py_DECREF(tp);
Line
Count
Source
548
46.2k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
46.2k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
46.2k
#  define _Py_CAST(type, expr) ((type)(expr))
14269
46.2k
}
14270
14271
static PyMethodDef ScandirIterator_methods[] = {
14272
    {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
14273
    {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
14274
    {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
14275
    {NULL}
14276
};
14277
14278
static PyType_Slot ScandirIteratorType_slots[] = {
14279
    {Py_tp_dealloc, ScandirIterator_dealloc},
14280
    {Py_tp_finalize, ScandirIterator_finalize},
14281
    {Py_tp_iter, PyObject_SelfIter},
14282
    {Py_tp_iternext, ScandirIterator_iternext},
14283
    {Py_tp_methods, ScandirIterator_methods},
14284
    {0, 0},
14285
};
14286
14287
static PyType_Spec ScandirIteratorType_spec = {
14288
    MODNAME ".ScandirIterator",
14289
    sizeof(ScandirIterator),
14290
    0,
14291
    // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
14292
    // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
14293
    (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE
14294
        | Py_TPFLAGS_DISALLOW_INSTANTIATION),
14295
    ScandirIteratorType_slots
14296
};
14297
14298
/*[clinic input]
14299
os.scandir
14300
14301
    path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
14302
14303
Return an iterator of DirEntry objects for given path.
14304
14305
path can be specified as either str, bytes, or a path-like object.  If path
14306
is bytes, the names of yielded DirEntry objects will also be bytes; in
14307
all other circumstances they will be str.
14308
14309
If path is None, uses the path='.'.
14310
[clinic start generated code]*/
14311
14312
static PyObject *
14313
os_scandir_impl(PyObject *module, path_t *path)
14314
/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
14315
46.2k
{
14316
46.2k
    ScandirIterator *iterator;
14317
#ifdef MS_WINDOWS
14318
    wchar_t *path_strW;
14319
#else
14320
46.2k
    const char *path_str;
14321
46.2k
#ifdef HAVE_FDOPENDIR
14322
46.2k
    int fd = -1;
14323
46.2k
#endif
14324
46.2k
#endif
14325
14326
46.2k
    if (PySys_Audit("os.scandir", "O",
  Branch (14326:9): [True: 0, False: 46.2k]
14327
46.2k
                    path->object ? path->object : Py_None) < 0) {
Line
Count
Source
654
1
#define Py_None (&_Py_NoneStruct)
  Branch (14327:21): [True: 46.2k, False: 1]
14328
0
        return NULL;
14329
0
    }
14330
14331
46.2k
    PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
14332
46.2k
    iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Line
Count
Source
134
46.2k
#define PyObject_New(type, typeobj) ((type *)_PyObject_New(typeobj))
14333
46.2k
    if (!iterator)
  Branch (14333:9): [True: 0, False: 46.2k]
14334
0
        return NULL;
14335
14336
#ifdef MS_WINDOWS
14337
    iterator->handle = INVALID_HANDLE_VALUE;
14338
#else
14339
46.2k
    iterator->dirp = NULL;
14340
46.2k
#endif
14341
14342
    /* Move the ownership to iterator->path */
14343
46.2k
    memcpy(&iterator->path, path, sizeof(path_t));
14344
46.2k
    memset(path, 0, sizeof(path_t));
14345
14346
#ifdef MS_WINDOWS
14347
    iterator->first_time = 1;
14348
14349
    path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
14350
    if (!path_strW)
14351
        goto error;
14352
14353
    Py_BEGIN_ALLOW_THREADS
14354
    iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
14355
    Py_END_ALLOW_THREADS
14356
14357
    PyMem_Free(path_strW);
14358
14359
    if (iterator->handle == INVALID_HANDLE_VALUE) {
14360
        path_error(&iterator->path);
14361
        goto error;
14362
    }
14363
#else /* POSIX */
14364
46.2k
    errno = 0;
14365
46.2k
#ifdef HAVE_FDOPENDIR
14366
46.2k
    if (iterator->path.fd != -1) {
  Branch (14366:9): [True: 11.6k, False: 34.5k]
14367
11.6k
      if (HAVE_FDOPENDIR_RUNTIME) {
Line
Count
Source
168
11.6k
#  define HAVE_FDOPENDIR_RUNTIME 1
  Branch (168:34): [Folded - Ignored]
14368
        /* closedir() closes the FD, so we duplicate it */
14369
11.6k
        fd = _Py_dup(iterator->path.fd);
14370
11.6k
        if (fd == -1)
  Branch (14370:13): [True: 0, False: 11.6k]
14371
0
            goto error;
14372
14373
11.6k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
11.6k
#define Py_BEGIN_ALLOW_THREADS { \
143
11.6k
                        PyThreadState *_save; \
144
11.6k
                        _save = PyEval_SaveThread();
14374
11.6k
        iterator->dirp = fdopendir(fd);
14375
11.6k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
11.6k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
11.6k
                 }
14376
11.6k
      } else {
14377
0
        PyErr_SetString(PyExc_TypeError,
14378
0
            "scandir: path should be string, bytes, os.PathLike or None, not int");
14379
0
        return NULL;
14380
0
      }
14381
11.6k
    }
14382
34.5k
    else
14383
34.5k
#endif
14384
34.5k
    {
14385
34.5k
        if (iterator->path.narrow)
  Branch (14385:13): [True: 34.5k, False: 1]
14386
34.5k
            path_str = iterator->path.narrow;
14387
1
        else
14388
1
            path_str = ".";
14389
14390
34.5k
        Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
34.5k
#define Py_BEGIN_ALLOW_THREADS { \
143
34.5k
                        PyThreadState *_save; \
144
34.5k
                        _save = PyEval_SaveThread();
14391
34.5k
        iterator->dirp = opendir(path_str);
14392
34.5k
        Py_END_ALLOW_THREADS
Line
Count
Source
147
34.5k
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
34.5k
                 }
14393
34.5k
    }
14394
14395
46.2k
    if (!iterator->dirp) {
  Branch (14395:9): [True: 452, False: 45.7k]
14396
452
        path_error(&iterator->path);
14397
452
#ifdef HAVE_FDOPENDIR
14398
452
        if (fd != -1) {
  Branch (14398:13): [True: 4, False: 448]
14399
4
            Py_BEGIN_ALLOW_THREADS
Line
Count
Source
142
4
#define Py_BEGIN_ALLOW_THREADS { \
143
4
                        PyThreadState *_save; \
144
4
                        _save = PyEval_SaveThread();
14400
4
            close(fd);
14401
4
            Py_END_ALLOW_THREADS
Line
Count
Source
147
4
#define Py_END_ALLOW_THREADS    PyEval_RestoreThread(_save); \
148
4
                 }
14402
4
        }
14403
452
#endif
14404
452
        goto error;
14405
452
    }
14406
45.7k
#endif
14407
14408
45.7k
    return (PyObject *)iterator;
14409
14410
452
error:
14411
452
    Py_DECREF(iterator);
Line
Count
Source
548
452
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
452
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
452
#  define _Py_CAST(type, expr) ((type)(expr))
14412
452
    return NULL;
14413
46.2k
}
14414
14415
/*
14416
    Return the file system path representation of the object.
14417
14418
    If the object is str or bytes, then allow it to pass through with
14419
    an incremented refcount. If the object defines __fspath__(), then
14420
    return the result of that method. All other types raise a TypeError.
14421
*/
14422
PyObject *
14423
PyOS_FSPath(PyObject *path)
14424
2.67M
{
14425
    /* For error message reasons, this function is manually inlined in
14426
       path_converter(). */
14427
2.67M
    PyObject *func = NULL;
14428
2.67M
    PyObject *path_repr = NULL;
14429
14430
2.67M
    if (PyUnicode_Check(path) || PyBytes_Check(path)) {
Line
Count
Source
115
2.67M
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
Line
Count
Source
782
5.35M
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (782:41): [True: 2.40M, False: 267k]
    if (PyUnicode_Check(path) || PyBytes_Check(path)) {
Line
Count
Source
31
267k
                 PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS)
Line
Count
Source
782
267k
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (782:41): [True: 247k, False: 19.7k]
14431
2.65M
        Py_INCREF(path);
Line
Count
Source
512
2.65M
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
2.65M
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
2.65M
#  define _Py_CAST(type, expr) ((type)(expr))
14432
2.65M
        return path;
14433
2.65M
    }
14434
14435
19.7k
    func = _PyObject_LookupSpecial(path, &_Py_ID(__fspath__));
Line
Count
Source
374
19.7k
     (_Py_SINGLETON(strings.identifiers._ ## NAME._ascii.ob_base))
Line
Count
Source
26
19.7k
    _Py_GLOBAL_OBJECT(singletons.NAME)
Line
Count
Source
24
19.7k
    _PyRuntime.global_objects.NAME
14436
19.7k
    if (NULL == func) {
  Branch (14436:9): [True: 95, False: 19.6k]
14437
95
        return PyErr_Format(PyExc_TypeError,
14438
95
                            "expected str, bytes or os.PathLike object, "
14439
95
                            "not %.200s",
14440
95
                            _PyType_Name(Py_TYPE(path)));
Line
Count
Source
138
95
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
95
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
95
#  define _Py_CAST(type, expr) ((type)(expr))
14441
95
    }
14442
14443
19.6k
    path_repr = _PyObject_CallNoArgs(func);
14444
19.6k
    Py_DECREF(func);
Line
Count
Source
548
19.6k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
19.6k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
19.6k
#  define _Py_CAST(type, expr) ((type)(expr))
14445
19.6k
    if (NULL == path_repr) {
  Branch (14445:9): [True: 4, False: 19.6k]
14446
4
        return NULL;
14447
4
    }
14448
14449
19.6k
    if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
Line
Count
Source
115
19.6k
    PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
Line
Count
Source
782
39.3k
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (782:41): [True: 19.6k, False: 37]
    if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
Line
Count
Source
31
37
                 PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS)
Line
Count
Source
782
37
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
  Branch (782:41): [True: 32, False: 5]
14450
5
        PyErr_Format(PyExc_TypeError,
14451
5
                     "expected %.200s.__fspath__() to return str or bytes, "
14452
5
                     "not %.200s", _PyType_Name(Py_TYPE(path)),
Line
Count
Source
138
5
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
5
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5
#  define _Py_CAST(type, expr) ((type)(expr))
14453
5
                     _PyType_Name(Py_TYPE(path_repr)));
Line
Count
Source
138
5
#  define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob))
Line
Count
Source
109
5
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5
#  define _Py_CAST(type, expr) ((type)(expr))
14454
5
        Py_DECREF(path_repr);
Line
Count
Source
548
5
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
5
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
5
#  define _Py_CAST(type, expr) ((type)(expr))
14455
5
        return NULL;
14456
5
    }
14457
14458
19.6k
    return path_repr;
14459
19.6k
}
14460
14461
/*[clinic input]
14462
os.fspath
14463
14464
    path: object
14465
14466
Return the file system path representation of the object.
14467
14468
If the object is str or bytes, then allow it to pass through as-is. If the
14469
object defines __fspath__(), then return the result of that method. All other
14470
types raise a TypeError.
14471
[clinic start generated code]*/
14472
14473
static PyObject *
14474
os_fspath_impl(PyObject *module, PyObject *path)
14475
/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
14476
1.88M
{
14477
1.88M
    return PyOS_FSPath(path);
14478
1.88M
}
14479
14480
#ifdef HAVE_GETRANDOM_SYSCALL
14481
/*[clinic input]
14482
os.getrandom
14483
14484
    size: Py_ssize_t
14485
    flags: int=0
14486
14487
Obtain a series of random bytes.
14488
[clinic start generated code]*/
14489
14490
static PyObject *
14491
os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
14492
/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
14493
6
{
14494
6
    PyObject *bytes;
14495
6
    Py_ssize_t n;
14496
14497
6
    if (size < 0) {
  Branch (14497:9): [True: 0, False: 6]
14498
0
        errno = EINVAL;
14499
0
        return posix_error();
14500
0
    }
14501
14502
6
    bytes = PyBytes_FromStringAndSize(NULL, size);
14503
6
    if (bytes == NULL) {
  Branch (14503:9): [True: 0, False: 6]
14504
0
        PyErr_NoMemory();
14505
0
        return NULL;
14506
0
    }
14507
14508
6
    while (1) {
  Branch (14508:12): [Folded - Ignored]
14509
6
        n = syscall(SYS_getrandom,
14510
6
                    PyBytes_AS_STRING(bytes),
Line
Count
Source
39
6
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
Line
Count
Source
109
6
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
6
#  define _Py_CAST(type, expr) ((type)(expr))
14511
6
                    PyBytes_GET_SIZE(bytes),
Line
Count
Source
45
6
#define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self))
Line
Count
Source
109
6
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
6
#  define _Py_CAST(type, expr) ((type)(expr))
14512
6
                    flags);
14513
6
        if (n < 0 && errno == EINTR) {
  Branch (14513:13): [True: 0, False: 6]
  Branch (14513:22): [True: 0, False: 0]
14514
0
            if (PyErr_CheckSignals() < 0) {
  Branch (14514:17): [True: 0, False: 0]
14515
0
                goto error;
14516
0
            }
14517
14518
            /* getrandom() was interrupted by a signal: retry */
14519
0
            continue;
14520
0
        }
14521
6
        break;
14522
6
    }
14523
14524
6
    if (n < 0) {
  Branch (14524:9): [True: 0, False: 6]
14525
0
        PyErr_SetFromErrno(PyExc_OSError);
14526
0
        goto error;
14527
0
    }
14528
14529
6
    if (n != size) {
  Branch (14529:9): [True: 0, False: 6]
14530
0
        _PyBytes_Resize(&bytes, n);
14531
0
    }
14532
14533
6
    return bytes;
14534
14535
0
error:
14536
0
    Py_DECREF(bytes);
Line
Count
Source
548
0
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
0
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
0
#  define _Py_CAST(type, expr) ((type)(expr))
14537
0
    return NULL;
14538
6
}
14539
#endif   /* HAVE_GETRANDOM_SYSCALL */
14540
14541
#ifdef MS_WINDOWS
14542
/* bpo-36085: Helper functions for managing DLL search directories
14543
 * on win32
14544
 */
14545
14546
typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
14547
typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
14548
14549
/*[clinic input]
14550
os._add_dll_directory
14551
14552
    path: path_t
14553
14554
Add a path to the DLL search path.
14555
14556
This search path is used when resolving dependencies for imported
14557
extension modules (the module itself is resolved through sys.path),
14558
and also by ctypes.
14559
14560
Returns an opaque value that may be passed to os.remove_dll_directory
14561
to remove this directory from the search path.
14562
[clinic start generated code]*/
14563
14564
static PyObject *
14565
os__add_dll_directory_impl(PyObject *module, path_t *path)
14566
/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
14567
{
14568
    HMODULE hKernel32;
14569
    PAddDllDirectory AddDllDirectory;
14570
    DLL_DIRECTORY_COOKIE cookie = 0;
14571
    DWORD err = 0;
14572
14573
    if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
14574
        return NULL;
14575
    }
14576
14577
    /* For Windows 7, we have to load this. As this will be a fairly
14578
       infrequent operation, just do it each time. Kernel32 is always
14579
       loaded. */
14580
    Py_BEGIN_ALLOW_THREADS
14581
    if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14582
        !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
14583
            hKernel32, "AddDllDirectory")) ||
14584
        !(cookie = (*AddDllDirectory)(path->wide))) {
14585
        err = GetLastError();
14586
    }
14587
    Py_END_ALLOW_THREADS
14588
14589
    if (err) {
14590
        return win32_error_object_err("add_dll_directory",
14591
                                      path->object, err);
14592
    }
14593
14594
    return PyCapsule_New(cookie, "DLL directory cookie", NULL);
14595
}
14596
14597
/*[clinic input]
14598
os._remove_dll_directory
14599
14600
    cookie: object
14601
14602
Removes a path from the DLL search path.
14603
14604
The parameter is an opaque value that was returned from
14605
os.add_dll_directory. You can only remove directories that you added
14606
yourself.
14607
[clinic start generated code]*/
14608
14609
static PyObject *
14610
os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
14611
/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
14612
{
14613
    HMODULE hKernel32;
14614
    PRemoveDllDirectory RemoveDllDirectory;
14615
    DLL_DIRECTORY_COOKIE cookieValue;
14616
    DWORD err = 0;
14617
14618
    if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
14619
        PyErr_SetString(PyExc_TypeError,
14620
            "Provided cookie was not returned from os.add_dll_directory");
14621
        return NULL;
14622
    }
14623
14624
    cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
14625
        cookie, "DLL directory cookie");
14626
14627
    /* For Windows 7, we have to load this. As this will be a fairly
14628
       infrequent operation, just do it each time. Kernel32 is always
14629
       loaded. */
14630
    Py_BEGIN_ALLOW_THREADS
14631
    if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14632
        !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
14633
            hKernel32, "RemoveDllDirectory")) ||
14634
        !(*RemoveDllDirectory)(cookieValue)) {
14635
        err = GetLastError();
14636
    }
14637
    Py_END_ALLOW_THREADS
14638
14639
    if (err) {
14640
        return win32_error_object_err("remove_dll_directory",
14641
                                      NULL, err);
14642
    }
14643
14644
    if (PyCapsule_SetName(cookie, NULL)) {
14645
        return NULL;
14646
    }
14647
14648
    Py_RETURN_NONE;
14649
}
14650
14651
#endif
14652
14653
14654
/* Only check if WIFEXITED is available: expect that it comes
14655
   with WEXITSTATUS, WIFSIGNALED, etc.
14656
14657
   os.waitstatus_to_exitcode() is implemented in C and not in Python, so
14658
   subprocess can safely call it during late Python finalization without
14659
   risking that used os attributes were set to None by finalize_modules(). */
14660
#if defined(WIFEXITED) || defined(MS_WINDOWS)
14661
/*[clinic input]
14662
os.waitstatus_to_exitcode
14663
14664
    status as status_obj: object
14665
14666
Convert a wait status to an exit code.
14667
14668
On Unix:
14669
14670
* If WIFEXITED(status) is true, return WEXITSTATUS(status).
14671
* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
14672
* Otherwise, raise a ValueError.
14673
14674
On Windows, return status shifted right by 8 bits.
14675
14676
On Unix, if the process is being traced or if waitpid() was called with
14677
WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
14678
This function must not be called if WIFSTOPPED(status) is true.
14679
[clinic start generated code]*/
14680
14681
static PyObject *
14682
os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
14683
/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
14684
5.66k
{
14685
5.66k
#ifndef MS_WINDOWS
14686
5.66k
    int status = _PyLong_AsInt(status_obj);
14687
5.66k
    if (status == -1 && PyErr_Occurred()) {
  Branch (14687:9): [True: 1, False: 5.66k]
  Branch (14687:25): [True: 1, False: 0]
14688
1
        return NULL;
14689
1
    }
14690
14691
5.66k
    WAIT_TYPE wait_status;
Line
Count
Source
450
5.66k
#  define WAIT_TYPE int
14692
5.66k
    WAIT_STATUS_INT(wait_status) = status;
Line
Count
Source
451
5.66k
#  define WAIT_STATUS_INT(s) (s)
14693
5.66k
    int exitcode;
14694
5.66k
    if (WIFEXITED(wait_status)) {
14695
5.37k
        exitcode = WEXITSTATUS(wait_status);
14696
        /* Sanity check to provide warranty on the function behavior.
14697
           It should not occur in practice */
14698
5.37k
        if (exitcode < 0) {
  Branch (14698:13): [True: 0, False: 5.37k]
14699
0
            PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
14700
0
            return NULL;
14701
0
        }
14702
5.37k
    }
14703
295
    else if (WIFSIGNALED(wait_status)) {
14704
295
        int signum = WTERMSIG(wait_status);
14705
        /* Sanity check to provide warranty on the function behavior.
14706
           It should not occurs in practice */
14707
295
        if (signum <= 0) {
  Branch (14707:13): [True: 0, False: 295]
14708
0
            PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
14709
0
            return NULL;
14710
0
        }
14711
295
        exitcode = -signum;
14712
295
    } else if (WIFSTOPPED(wait_status)) {
14713
        /* Status only received if the process is being traced
14714
           or if waitpid() was called with WUNTRACED option. */
14715
0
        int signum = WSTOPSIG(wait_status);
14716
0
        PyErr_Format(PyExc_ValueError,
14717
0
                     "process stopped by delivery of signal %i",
14718
0
                     signum);
14719
0
        return NULL;
14720
0
    }
14721
0
    else {
14722
0
        PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
14723
0
        return NULL;
14724
0
    }
14725
5.66k
    return PyLong_FromLong(exitcode);
14726
#else
14727
    /* Windows implementation: see os.waitpid() implementation
14728
       which uses _cwait(). */
14729
    unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
14730
    if (status == (unsigned long long)-1 && PyErr_Occurred()) {
14731
        return NULL;
14732
    }
14733
14734
    unsigned long long exitcode = (status >> 8);
14735
    /* ExitProcess() accepts an UINT type:
14736
       reject exit code which doesn't fit in an UINT */
14737
    if (exitcode > UINT_MAX) {
14738
        PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
14739
        return NULL;
14740
    }
14741
    return PyLong_FromUnsignedLong((unsigned long)exitcode);
14742
#endif
14743
5.66k
}
14744
#endif
14745
14746
14747
static PyMethodDef posix_methods[] = {
14748
14749
    OS_STAT_METHODDEF
14750
    OS_ACCESS_METHODDEF
14751
    OS_TTYNAME_METHODDEF
14752
    OS_CHDIR_METHODDEF
14753
    OS_CHFLAGS_METHODDEF
14754
    OS_CHMOD_METHODDEF
14755
    OS_FCHMOD_METHODDEF
14756
    OS_LCHMOD_METHODDEF
14757
    OS_CHOWN_METHODDEF
14758
    OS_FCHOWN_METHODDEF
14759
    OS_LCHOWN_METHODDEF
14760
    OS_LCHFLAGS_METHODDEF
14761
    OS_CHROOT_METHODDEF
14762
    OS_CTERMID_METHODDEF
14763
    OS_GETCWD_METHODDEF
14764
    OS_GETCWDB_METHODDEF
14765
    OS_LINK_METHODDEF
14766
    OS_LISTDIR_METHODDEF
14767
    OS_LSTAT_METHODDEF
14768
    OS_MKDIR_METHODDEF
14769
    OS_NICE_METHODDEF
14770
    OS_GETPRIORITY_METHODDEF
14771
    OS_SETPRIORITY_METHODDEF
14772
    OS_POSIX_SPAWN_METHODDEF
14773
    OS_POSIX_SPAWNP_METHODDEF
14774
    OS_READLINK_METHODDEF
14775
    OS_COPY_FILE_RANGE_METHODDEF
14776
    OS_SPLICE_METHODDEF
14777
    OS_RENAME_METHODDEF
14778
    OS_REPLACE_METHODDEF
14779
    OS_RMDIR_METHODDEF
14780
    OS_SYMLINK_METHODDEF
14781
    OS_SYSTEM_METHODDEF
14782
    OS_UMASK_METHODDEF
14783
    OS_UNAME_METHODDEF
14784
    OS_UNLINK_METHODDEF
14785
    OS_REMOVE_METHODDEF
14786
    OS_UTIME_METHODDEF
14787
    OS_TIMES_METHODDEF
14788
    OS__EXIT_METHODDEF
14789
    OS__FCOPYFILE_METHODDEF
14790
    OS_EXECV_METHODDEF
14791
    OS_EXECVE_METHODDEF
14792
    OS_SPAWNV_METHODDEF
14793
    OS_SPAWNVE_METHODDEF
14794
    OS_FORK1_METHODDEF
14795
    OS_FORK_METHODDEF
14796
    OS_REGISTER_AT_FORK_METHODDEF
14797
    OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14798
    OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14799
    OS_SCHED_GETPARAM_METHODDEF
14800
    OS_SCHED_GETSCHEDULER_METHODDEF
14801
    OS_SCHED_RR_GET_INTERVAL_METHODDEF
14802
    OS_SCHED_SETPARAM_METHODDEF
14803
    OS_SCHED_SETSCHEDULER_METHODDEF
14804
    OS_SCHED_YIELD_METHODDEF
14805
    OS_SCHED_SETAFFINITY_METHODDEF
14806
    OS_SCHED_GETAFFINITY_METHODDEF
14807
    OS_OPENPTY_METHODDEF
14808
    OS_LOGIN_TTY_METHODDEF
14809
    OS_FORKPTY_METHODDEF
14810
    OS_GETEGID_METHODDEF
14811
    OS_GETEUID_METHODDEF
14812
    OS_GETGID_METHODDEF
14813
    OS_GETGROUPLIST_METHODDEF
14814
    OS_GETGROUPS_METHODDEF
14815
    OS_GETPID_METHODDEF
14816
    OS_GETPGRP_METHODDEF
14817
    OS_GETPPID_METHODDEF
14818
    OS_GETUID_METHODDEF
14819
    OS_GETLOGIN_METHODDEF
14820
    OS_KILL_METHODDEF
14821
    OS_KILLPG_METHODDEF
14822
    OS_PLOCK_METHODDEF
14823
    OS_STARTFILE_METHODDEF
14824
    OS_SETUID_METHODDEF
14825
    OS_SETEUID_METHODDEF
14826
    OS_SETREUID_METHODDEF
14827
    OS_SETGID_METHODDEF
14828
    OS_SETEGID_METHODDEF
14829
    OS_SETREGID_METHODDEF
14830
    OS_SETGROUPS_METHODDEF
14831
    OS_INITGROUPS_METHODDEF
14832
    OS_GETPGID_METHODDEF
14833
    OS_SETPGRP_METHODDEF
14834
    OS_WAIT_METHODDEF
14835
    OS_WAIT3_METHODDEF
14836
    OS_WAIT4_METHODDEF
14837
    OS_WAITID_METHODDEF
14838
    OS_WAITPID_METHODDEF
14839
    OS_PIDFD_OPEN_METHODDEF
14840
    OS_GETSID_METHODDEF
14841
    OS_SETSID_METHODDEF
14842
    OS_SETPGID_METHODDEF
14843
    OS_TCGETPGRP_METHODDEF
14844
    OS_TCSETPGRP_METHODDEF
14845
    OS_OPEN_METHODDEF
14846
    OS_CLOSE_METHODDEF
14847
    OS_CLOSERANGE_METHODDEF
14848
    OS_DEVICE_ENCODING_METHODDEF
14849
    OS_DUP_METHODDEF
14850
    OS_DUP2_METHODDEF
14851
    OS_LOCKF_METHODDEF
14852
    OS_LSEEK_METHODDEF
14853
    OS_READ_METHODDEF
14854
    OS_READV_METHODDEF
14855
    OS_PREAD_METHODDEF
14856
    OS_PREADV_METHODDEF
14857
    OS_WRITE_METHODDEF
14858
    OS_WRITEV_METHODDEF
14859
    OS_PWRITE_METHODDEF
14860
    OS_PWRITEV_METHODDEF
14861
    OS_SENDFILE_METHODDEF
14862
    OS_FSTAT_METHODDEF
14863
    OS_ISATTY_METHODDEF
14864
    OS_PIPE_METHODDEF
14865
    OS_PIPE2_METHODDEF
14866
    OS_MKFIFO_METHODDEF
14867
    OS_MKNOD_METHODDEF
14868
    OS_MAJOR_METHODDEF
14869
    OS_MINOR_METHODDEF
14870
    OS_MAKEDEV_METHODDEF
14871
    OS_FTRUNCATE_METHODDEF
14872
    OS_TRUNCATE_METHODDEF
14873
    OS_POSIX_FALLOCATE_METHODDEF
14874
    OS_POSIX_FADVISE_METHODDEF
14875
    OS_PUTENV_METHODDEF
14876
    OS_UNSETENV_METHODDEF
14877
    OS_STRERROR_METHODDEF
14878
    OS_FCHDIR_METHODDEF
14879
    OS_FSYNC_METHODDEF
14880
    OS_SYNC_METHODDEF
14881
    OS_FDATASYNC_METHODDEF
14882
    OS_WCOREDUMP_METHODDEF
14883
    OS_WIFCONTINUED_METHODDEF
14884
    OS_WIFSTOPPED_METHODDEF
14885
    OS_WIFSIGNALED_METHODDEF
14886
    OS_WIFEXITED_METHODDEF
14887
    OS_WEXITSTATUS_METHODDEF
14888
    OS_WTERMSIG_METHODDEF
14889
    OS_WSTOPSIG_METHODDEF
14890
    OS_FSTATVFS_METHODDEF
14891
    OS_STATVFS_METHODDEF
14892
    OS_CONFSTR_METHODDEF
14893
    OS_SYSCONF_METHODDEF
14894
    OS_FPATHCONF_METHODDEF
14895
    OS_PATHCONF_METHODDEF
14896
    OS_ABORT_METHODDEF
14897
    OS__GETFULLPATHNAME_METHODDEF
14898
    OS__GETDISKUSAGE_METHODDEF
14899
    OS__GETFINALPATHNAME_METHODDEF
14900
    OS__GETVOLUMEPATHNAME_METHODDEF
14901
    OS__PATH_SPLITROOT_METHODDEF
14902
    OS__PATH_NORMPATH_METHODDEF
14903
    OS_GETLOADAVG_METHODDEF
14904
    OS_URANDOM_METHODDEF
14905
    OS_SETRESUID_METHODDEF
14906
    OS_SETRESGID_METHODDEF
14907
    OS_GETRESUID_METHODDEF
14908
    OS_GETRESGID_METHODDEF
14909
14910
    OS_GETXATTR_METHODDEF
14911
    OS_SETXATTR_METHODDEF
14912
    OS_REMOVEXATTR_METHODDEF
14913
    OS_LISTXATTR_METHODDEF
14914
14915
    OS_GET_TERMINAL_SIZE_METHODDEF
14916
    OS_CPU_COUNT_METHODDEF
14917
    OS_GET_INHERITABLE_METHODDEF
14918
    OS_SET_INHERITABLE_METHODDEF
14919
    OS_GET_HANDLE_INHERITABLE_METHODDEF
14920
    OS_SET_HANDLE_INHERITABLE_METHODDEF
14921
    OS_GET_BLOCKING_METHODDEF
14922
    OS_SET_BLOCKING_METHODDEF
14923
    OS_SCANDIR_METHODDEF
14924
    OS_FSPATH_METHODDEF
14925
    OS_GETRANDOM_METHODDEF
14926
    OS_MEMFD_CREATE_METHODDEF
14927
    OS_EVENTFD_METHODDEF
14928
    OS_EVENTFD_READ_METHODDEF
14929
    OS_EVENTFD_WRITE_METHODDEF
14930
    OS__ADD_DLL_DIRECTORY_METHODDEF
14931
    OS__REMOVE_DLL_DIRECTORY_METHODDEF
14932
    OS_WAITSTATUS_TO_EXITCODE_METHODDEF
14933
    {NULL,              NULL}            /* Sentinel */
14934
};
14935
14936
static int
14937
all_ins(PyObject *m)
14938
278
{
14939
278
#ifdef F_OK
14940
278
    if (PyModule_AddIntMacro(m, F_OK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14941
278
#endif
14942
278
#ifdef R_OK
14943
278
    if (PyModule_AddIntMacro(m, R_OK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14944
278
#endif
14945
278
#ifdef W_OK
14946
278
    if (PyModule_AddIntMacro(m, W_OK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14947
278
#endif
14948
278
#ifdef X_OK
14949
278
    if (PyModule_AddIntMacro(m, X_OK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14950
278
#endif
14951
278
#ifdef NGROUPS_MAX
14952
278
    if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14953
278
#endif
14954
278
#ifdef TMP_MAX
14955
278
    if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14956
278
#endif
14957
278
#ifdef WCONTINUED
14958
278
    if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14959
278
#endif
14960
278
#ifdef WNOHANG
14961
278
    if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14962
278
#endif
14963
278
#ifdef WUNTRACED
14964
278
    if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14965
278
#endif
14966
278
#ifdef O_RDONLY
14967
278
    if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14968
278
#endif
14969
278
#ifdef O_WRONLY
14970
278
    if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14971
278
#endif
14972
278
#ifdef O_RDWR
14973
278
    if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14974
278
#endif
14975
278
#ifdef O_NDELAY
14976
278
    if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14977
278
#endif
14978
278
#ifdef O_NONBLOCK
14979
278
    if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14980
278
#endif
14981
278
#ifdef O_APPEND
14982
278
    if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14983
278
#endif
14984
278
#ifdef O_DSYNC
14985
278
    if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14986
278
#endif
14987
278
#ifdef O_RSYNC
14988
278
    if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14989
278
#endif
14990
278
#ifdef O_SYNC
14991
278
    if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14992
278
#endif
14993
278
#ifdef O_NOCTTY
14994
278
    if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14995
278
#endif
14996
278
#ifdef O_CREAT
14997
278
    if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
14998
278
#endif
14999
278
#ifdef O_EXCL
15000
278
    if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15001
278
#endif
15002
278
#ifdef O_TRUNC
15003
278
    if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15004
278
#endif
15005
#ifdef O_BINARY
15006
    if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
15007
#endif
15008
#ifdef O_TEXT
15009
    if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
15010
#endif
15011
#ifdef O_XATTR
15012
    if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
15013
#endif
15014
278
#ifdef O_LARGEFILE
15015
278
    if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15016
278
#endif
15017
278
#ifndef __GNU__
15018
#ifdef O_SHLOCK
15019
    if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
15020
#endif
15021
#ifdef O_EXLOCK
15022
    if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
15023
#endif
15024
278
#endif
15025
#ifdef O_EXEC
15026
    if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
15027
#endif
15028
#ifdef O_SEARCH
15029
    if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
15030
#endif
15031
278
#ifdef O_PATH
15032
278
    if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15033
278
#endif
15034
#ifdef O_TTY_INIT
15035
    if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
15036
#endif
15037
278
#ifdef O_TMPFILE
15038
278
    if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15039
278
#endif
15040
278
#ifdef PRIO_PROCESS
15041
278
    if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15042
278
#endif
15043
278
#ifdef PRIO_PGRP
15044
278
    if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15045
278
#endif
15046
278
#ifdef PRIO_USER
15047
278
    if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15048
278
#endif
15049
278
#ifdef O_CLOEXEC
15050
278
    if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15051
278
#endif
15052
278
#ifdef O_ACCMODE
15053
278
    if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15054
278
#endif
15055
#ifdef O_EVTONLY
15056
    if (PyModule_AddIntMacro(m, O_EVTONLY)) return -1;
15057
#endif
15058
278
#ifdef O_FSYNC
15059
278
    if (PyModule_AddIntMacro(m, O_FSYNC)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15060
278
#endif
15061
#ifdef O_SYMLINK
15062
    if (PyModule_AddIntMacro(m, O_SYMLINK)) return -1;
15063
#endif
15064
15065
278
#ifdef SEEK_HOLE
15066
278
    if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15067
278
#endif
15068
278
#ifdef SEEK_DATA
15069
278
    if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15070
278
#endif
15071
15072
/* MS Windows */
15073
#ifdef O_NOINHERIT
15074
    /* Don't inherit in child processes. */
15075
    if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
15076
#endif
15077
#ifdef _O_SHORT_LIVED
15078
    /* Optimize for short life (keep in memory). */
15079
    /* MS forgot to define this one with a non-underscore form too. */
15080
    if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
15081
#endif
15082
#ifdef O_TEMPORARY
15083
    /* Automatically delete when last handle is closed. */
15084
    if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
15085
#endif
15086
#ifdef O_RANDOM
15087
    /* Optimize for random access. */
15088
    if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
15089
#endif
15090
#ifdef O_SEQUENTIAL
15091
    /* Optimize for sequential access. */
15092
    if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
15093
#endif
15094
15095
/* GNU extensions. */
15096
278
#ifdef O_ASYNC
15097
    /* Send a SIGIO signal whenever input or output
15098
       becomes available on file descriptor */
15099
278
    if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15100
278
#endif
15101
278
#ifdef O_DIRECT
15102
    /* Direct disk access. */
15103
278
    if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15104
278
#endif
15105
278
#ifdef O_DIRECTORY
15106
    /* Must be a directory.      */
15107
278
    if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15108
278
#endif
15109
278
#ifdef O_NOFOLLOW
15110
    /* Do not follow links.      */
15111
278
    if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15112
278
#endif
15113
#ifdef O_NOFOLLOW_ANY
15114
    if (PyModule_AddIntMacro(m, O_NOFOLLOW_ANY)) return -1;
15115
#endif
15116
#ifdef O_NOLINKS
15117
    /* Fails if link count of the named file is greater than 1 */
15118
    if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
15119
#endif
15120
278
#ifdef O_NOATIME
15121
    /* Do not update the access time. */
15122
278
    if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15123
278
#endif
15124
15125
    /* These come from sysexits.h */
15126
278
#ifdef EX_OK
15127
278
    if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15128
278
#endif /* EX_OK */
15129
278
#ifdef EX_USAGE
15130
278
    if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15131
278
#endif /* EX_USAGE */
15132
278
#ifdef EX_DATAERR
15133
278
    if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15134
278
#endif /* EX_DATAERR */
15135
278
#ifdef EX_NOINPUT
15136
278
    if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15137
278
#endif /* EX_NOINPUT */
15138
278
#ifdef EX_NOUSER
15139
278
    if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15140
278
#endif /* EX_NOUSER */
15141
278
#ifdef EX_NOHOST
15142
278
    if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15143
278
#endif /* EX_NOHOST */
15144
278
#ifdef EX_UNAVAILABLE
15145
278
    if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15146
278
#endif /* EX_UNAVAILABLE */
15147
278
#ifdef EX_SOFTWARE
15148
278
    if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15149
278
#endif /* EX_SOFTWARE */
15150
278
#ifdef EX_OSERR
15151
278
    if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15152
278
#endif /* EX_OSERR */
15153
278
#ifdef EX_OSFILE
15154
278
    if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15155
278
#endif /* EX_OSFILE */
15156
278
#ifdef EX_CANTCREAT
15157
278
    if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15158
278
#endif /* EX_CANTCREAT */
15159
278
#ifdef EX_IOERR
15160
278
    if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15161
278
#endif /* EX_IOERR */
15162
278
#ifdef EX_TEMPFAIL
15163
278
    if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15164
278
#endif /* EX_TEMPFAIL */
15165
278
#ifdef EX_PROTOCOL
15166
278
    if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15167
278
#endif /* EX_PROTOCOL */
15168
278
#ifdef EX_NOPERM
15169
278
    if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15170
278
#endif /* EX_NOPERM */
15171
278
#ifdef EX_CONFIG
15172
278
    if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15173
278
#endif /* EX_CONFIG */
15174
#ifdef EX_NOTFOUND
15175
    if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
15176
#endif /* EX_NOTFOUND */
15177
15178
    /* statvfs */
15179
278
#ifdef ST_RDONLY
15180
278
    if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15181
278
#endif /* ST_RDONLY */
15182
278
#ifdef ST_NOSUID
15183
278
    if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15184
278
#endif /* ST_NOSUID */
15185
15186
       /* GNU extensions */
15187
278
#ifdef ST_NODEV
15188
278
    if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15189
278
#endif /* ST_NODEV */
15190
278
#ifdef ST_NOEXEC
15191
278
    if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15192
278
#endif /* ST_NOEXEC */
15193
278
#ifdef ST_SYNCHRONOUS
15194
278
    if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15195
278
#endif /* ST_SYNCHRONOUS */
15196
278
#ifdef ST_MANDLOCK
15197
278
    if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15198
278
#endif /* ST_MANDLOCK */
15199
278
#ifdef ST_WRITE
15200
278
    if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15201
278
#endif /* ST_WRITE */
15202
278
#ifdef ST_APPEND
15203
278
    if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15204
278
#endif /* ST_APPEND */
15205
278
#ifdef ST_NOATIME
15206
278
    if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15207
278
#endif /* ST_NOATIME */
15208
278
#ifdef ST_NODIRATIME
15209
278
    if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15210
278
#endif /* ST_NODIRATIME */
15211
278
#ifdef ST_RELATIME
15212
278
    if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15213
278
#endif /* ST_RELATIME */
15214
15215
    /* FreeBSD sendfile() constants */
15216
#ifdef SF_NODISKIO
15217
    if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
15218
#endif
15219
    /* is obsolete since the 11.x release */
15220
#ifdef SF_MNOWAIT
15221
    if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
15222
#endif
15223
#ifdef SF_SYNC
15224
    if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
15225
#endif
15226
#ifdef SF_NOCACHE
15227
    if (PyModule_AddIntMacro(m, SF_NOCACHE)) return -1;
15228
#endif
15229
15230
    /* constants for posix_fadvise */
15231
278
#ifdef POSIX_FADV_NORMAL
15232
278
    if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15233
278
#endif
15234
278
#ifdef POSIX_FADV_SEQUENTIAL
15235
278
    if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15236
278
#endif
15237
278
#ifdef POSIX_FADV_RANDOM
15238
278
    if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15239
278
#endif
15240
278
#ifdef POSIX_FADV_NOREUSE
15241
278
    if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15242
278
#endif
15243
278
#ifdef POSIX_FADV_WILLNEED
15244
278
    if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15245
278
#endif
15246
278
#ifdef POSIX_FADV_DONTNEED
15247
278
    if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15248
278
#endif
15249
15250
    /* constants for waitid */
15251
278
#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
15252
278
    if (PyModule_AddIntMacro(m, P_PID)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15253
278
    if (PyModule_AddIntMacro(m, P_PGID)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15254
278
    if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15255
278
#ifdef P_PIDFD
15256
278
    if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15257
278
#endif
15258
#ifdef PIDFD_NONBLOCK
15259
    if (PyModule_AddIntMacro(m, PIDFD_NONBLOCK)) return -1;
15260
#endif
15261
278
#endif
15262
278
#ifdef WEXITED
15263
278
    if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15264
278
#endif
15265
278
#ifdef WNOWAIT
15266
278
    if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15267
278
#endif
15268
278
#ifdef WSTOPPED
15269
278
    if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15270
278
#endif
15271
278
#ifdef CLD_EXITED
15272
278
    if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15273
278
#endif
15274
278
#ifdef CLD_KILLED
15275
278
    if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15276
278
#endif
15277
278
#ifdef CLD_DUMPED
15278
278
    if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15279
278
#endif
15280
278
#ifdef CLD_TRAPPED
15281
278
    if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15282
278
#endif
15283
278
#ifdef CLD_STOPPED
15284
278
    if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15285
278
#endif
15286
278
#ifdef CLD_CONTINUED
15287
278
    if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15288
278
#endif
15289
15290
    /* constants for lockf */
15291
278
#ifdef F_LOCK
15292
278
    if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15293
278
#endif
15294
278
#ifdef F_TLOCK
15295
278
    if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15296
278
#endif
15297
278
#ifdef F_ULOCK
15298
278
    if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15299
278
#endif
15300
278
#ifdef F_TEST
15301
278
    if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15302
278
#endif
15303
15304
278
#ifdef RWF_DSYNC
15305
278
    if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
  Branch (15305:9): [True: 0, False: 278]
15306
278
#endif
15307
278
#ifdef RWF_HIPRI
15308
278
    if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
  Branch (15308:9): [True: 0, False: 278]
15309
278
#endif
15310
278
#ifdef RWF_SYNC
15311
278
    if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
  Branch (15311:9): [True: 0, False: 278]
15312
278
#endif
15313
278
#ifdef RWF_NOWAIT
15314
278
    if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
  Branch (15314:9): [True: 0, False: 278]
15315
278
#endif
15316
278
#ifdef RWF_APPEND
15317
278
    if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1;
  Branch (15317:9): [True: 0, False: 278]
15318
278
#endif
15319
15320
/* constants for splice */
15321
278
#if defined(HAVE_SPLICE) && defined(__linux__)
15322
278
    if (PyModule_AddIntConstant(m, "SPLICE_F_MOVE", SPLICE_F_MOVE)) return -1;
  Branch (15322:9): [True: 0, False: 278]
15323
278
    if (PyModule_AddIntConstant(m, "SPLICE_F_NONBLOCK", SPLICE_F_NONBLOCK)) return -1;
  Branch (15323:9): [True: 0, False: 278]
15324
278
    if (PyModule_AddIntConstant(m, "SPLICE_F_MORE", SPLICE_F_MORE)) return -1;
  Branch (15324:9): [True: 0, False: 278]
15325
278
#endif
15326
15327
/* constants for posix_spawn */
15328
278
#ifdef HAVE_POSIX_SPAWN
15329
278
    if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
  Branch (15329:9): [True: 0, False: 278]
15330
278
    if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
  Branch (15330:9): [True: 0, False: 278]
15331
278
    if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
  Branch (15331:9): [True: 0, False: 278]
15332
278
#endif
15333
15334
#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
15335
    if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
15336
    if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
15337
    if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
15338
#endif
15339
#ifdef HAVE_SPAWNV
15340
    if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
15341
    if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
15342
#endif
15343
15344
278
#ifdef HAVE_SCHED_H
15345
278
#ifdef SCHED_OTHER
15346
278
    if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15347
278
#endif
15348
278
#ifdef SCHED_FIFO
15349
278
    if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15350
278
#endif
15351
278
#ifdef SCHED_RR
15352
278
    if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15353
278
#endif
15354
#ifdef SCHED_SPORADIC
15355
    if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
15356
#endif
15357
278
#ifdef SCHED_BATCH
15358
278
    if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15359
278
#endif
15360
278
#ifdef SCHED_IDLE
15361
278
    if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15362
278
#endif
15363
278
#ifdef SCHED_RESET_ON_FORK
15364
278
    if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15365
278
#endif
15366
#ifdef SCHED_SYS
15367
    if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
15368
#endif
15369
#ifdef SCHED_IA
15370
    if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
15371
#endif
15372
#ifdef SCHED_FSS
15373
    if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
15374
#endif
15375
#ifdef SCHED_FX
15376
    if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
15377
#endif
15378
278
#endif
15379
15380
278
#ifdef USE_XATTRS
15381
278
    if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15382
278
    if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15383
278
    if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15384
278
#endif
15385
15386
278
#if HAVE_DECL_RTLD_LAZY
15387
278
    if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15388
278
#endif
15389
278
#if HAVE_DECL_RTLD_NOW
15390
278
    if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15391
278
#endif
15392
278
#if HAVE_DECL_RTLD_GLOBAL
15393
278
    if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15394
278
#endif
15395
278
#if HAVE_DECL_RTLD_LOCAL
15396
278
    if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15397
278
#endif
15398
278
#if HAVE_DECL_RTLD_NODELETE
15399
278
    if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15400
278
#endif
15401
278
#if HAVE_DECL_RTLD_NOLOAD
15402
278
    if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15403
278
#endif
15404
278
#if HAVE_DECL_RTLD_DEEPBIND
15405
278
    if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15406
278
#endif
15407
#if HAVE_DECL_RTLD_MEMBER
15408
    if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
15409
#endif
15410
15411
278
#ifdef HAVE_GETRANDOM_SYSCALL
15412
278
    if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15413
278
    if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15414
278
#endif
15415
278
#ifdef HAVE_MEMFD_CREATE
15416
278
    if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15417
278
    if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15418
278
#ifdef MFD_HUGETLB
15419
278
    if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15420
278
#endif
15421
278
#ifdef MFD_HUGE_SHIFT
15422
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15423
278
#endif
15424
278
#ifdef MFD_HUGE_MASK
15425
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15426
278
#endif
15427
278
#ifdef MFD_HUGE_64KB
15428
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15429
278
#endif
15430
278
#ifdef MFD_HUGE_512KB
15431
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15432
278
#endif
15433
278
#ifdef MFD_HUGE_1MB
15434
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15435
278
#endif
15436
278
#ifdef MFD_HUGE_2MB
15437
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15438
278
#endif
15439
278
#ifdef MFD_HUGE_8MB
15440
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15441
278
#endif
15442
278
#ifdef MFD_HUGE_16MB
15443
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15444
278
#endif
15445
278
#ifdef MFD_HUGE_32MB
15446
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15447
278
#endif
15448
278
#ifdef MFD_HUGE_256MB
15449
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15450
278
#endif
15451
278
#ifdef MFD_HUGE_512MB
15452
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15453
278
#endif
15454
278
#ifdef MFD_HUGE_1GB
15455
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15456
278
#endif
15457
278
#ifdef MFD_HUGE_2GB
15458
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15459
278
#endif
15460
278
#ifdef MFD_HUGE_16GB
15461
278
    if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15462
278
#endif
15463
278
#endif /* HAVE_MEMFD_CREATE */
15464
15465
278
#ifdef HAVE_EVENTFD
15466
278
    if (PyModule_AddIntMacro(m, EFD_CLOEXEC)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15467
278
    if (PyModule_AddIntMacro(m, EFD_NONBLOCK)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15468
278
    if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1;
Line
Count
Source
59
278
#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c))
  Branch (59:36): [True: 0, False: 278]
15469
278
#endif
15470
15471
#if defined(__APPLE__)
15472
    if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
15473
    if (PyModule_AddIntConstant(m, "_COPYFILE_STAT", COPYFILE_STAT)) return -1;
15474
    if (PyModule_AddIntConstant(m, "_COPYFILE_ACL", COPYFILE_ACL)) return -1;
15475
    if (PyModule_AddIntConstant(m, "_COPYFILE_XATTR", COPYFILE_XATTR)) return -1;
15476
#endif
15477
15478
#ifdef MS_WINDOWS
15479
    if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
15480
    if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
15481
    if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
15482
    if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
15483
    if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
15484
#endif
15485
15486
278
    return 0;
15487
278
}
15488
15489
15490
15491
#define PROBE(name, test) \
15492
   static int name(void)  \
15493
3.89k
   {                      \
15494
3.89k
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
  Branch (15494:11): [Folded - Ignored]
15495
3.89k
          return 1;       \
15496
3.89k
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
3.89k
   }
posixmodule.c:probe_faccessat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_fchmodat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_fchownat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_fdopendir
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_fstatat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_futimens
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_linkat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_mkdirat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_openat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_readlinkat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_renameat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_symlinkat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_unlinkat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
posixmodule.c:probe_utimensat
Line
Count
Source
15493
278
   {                      \
15494
278
      if (test) {        \
  Branch (15494:11): [Folded - Ignored]
15495
278
          return 1;       \
15496
278
      } else {            \
15497
0
          return 0;       \
15498
0
      }                   \
15499
278
   }
15500
15501
#ifdef HAVE_FSTATAT
15502
PROBE(probe_fstatat, HAVE_FSTATAT_RUNTIME)
15503
#endif
15504
15505
#ifdef HAVE_FACCESSAT
15506
PROBE(probe_faccessat, HAVE_FACCESSAT_RUNTIME)
15507
#endif
15508
15509
#ifdef HAVE_FCHMODAT
15510
PROBE(probe_fchmodat, HAVE_FCHMODAT_RUNTIME)
15511
#endif
15512
15513
#ifdef HAVE_FCHOWNAT
15514
PROBE(probe_fchownat, HAVE_FCHOWNAT_RUNTIME)
15515
#endif
15516
15517
#ifdef HAVE_LINKAT
15518
PROBE(probe_linkat, HAVE_LINKAT_RUNTIME)
15519
#endif
15520
15521
#ifdef HAVE_FDOPENDIR
15522
PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME)
15523
#endif
15524
15525
#ifdef HAVE_MKDIRAT
15526
PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME)
15527
#endif
15528
15529
#ifdef HAVE_RENAMEAT
15530
PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME)
15531
#endif
15532
15533
#ifdef HAVE_UNLINKAT
15534
PROBE(probe_unlinkat, HAVE_UNLINKAT_RUNTIME)
15535
#endif
15536
15537
#ifdef HAVE_OPENAT
15538
PROBE(probe_openat, HAVE_OPENAT_RUNTIME)
15539
#endif
15540
15541
#ifdef HAVE_READLINKAT
15542
PROBE(probe_readlinkat, HAVE_READLINKAT_RUNTIME)
15543
#endif
15544
15545
#ifdef HAVE_SYMLINKAT
15546
PROBE(probe_symlinkat, HAVE_SYMLINKAT_RUNTIME)
15547
#endif
15548
15549
#ifdef HAVE_FUTIMENS
15550
PROBE(probe_futimens, HAVE_FUTIMENS_RUNTIME)
15551
#endif
15552
15553
#ifdef HAVE_UTIMENSAT
15554
PROBE(probe_utimensat, HAVE_UTIMENSAT_RUNTIME)
15555
#endif
15556
15557
15558
15559
15560
static const struct have_function {
15561
    const char * const label;
15562
    int (*probe)(void);
15563
} have_functions[] = {
15564
15565
#ifdef HAVE_EVENTFD
15566
    {"HAVE_EVENTFD", NULL},
15567
#endif
15568
15569
#ifdef HAVE_FACCESSAT
15570
    { "HAVE_FACCESSAT", probe_faccessat },
15571
#endif
15572
15573
#ifdef HAVE_FCHDIR
15574
    { "HAVE_FCHDIR", NULL },
15575
#endif
15576
15577
#ifdef HAVE_FCHMOD
15578
    { "HAVE_FCHMOD", NULL },
15579
#endif
15580
15581
#ifdef HAVE_FCHMODAT
15582
    { "HAVE_FCHMODAT", probe_fchmodat },
15583
#endif
15584
15585
#ifdef HAVE_FCHOWN
15586
    { "HAVE_FCHOWN", NULL },
15587
#endif
15588
15589
#ifdef HAVE_FCHOWNAT
15590
    { "HAVE_FCHOWNAT", probe_fchownat },
15591
#endif
15592
15593
#ifdef HAVE_FEXECVE
15594
    { "HAVE_FEXECVE", NULL },
15595
#endif
15596
15597
#ifdef HAVE_FDOPENDIR
15598
    { "HAVE_FDOPENDIR", probe_fdopendir },
15599
#endif
15600
15601
#ifdef HAVE_FPATHCONF
15602
    { "HAVE_FPATHCONF", NULL },
15603
#endif
15604
15605
#ifdef HAVE_FSTATAT
15606
    { "HAVE_FSTATAT", probe_fstatat },
15607
#endif
15608
15609
#ifdef HAVE_FSTATVFS
15610
    { "HAVE_FSTATVFS", NULL },
15611
#endif
15612
15613
#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
15614
    { "HAVE_FTRUNCATE", NULL },
15615
#endif
15616
15617
#ifdef HAVE_FUTIMENS
15618
    { "HAVE_FUTIMENS", probe_futimens },
15619
#endif
15620
15621
#ifdef HAVE_FUTIMES
15622
    { "HAVE_FUTIMES", NULL },
15623
#endif
15624
15625
#ifdef HAVE_FUTIMESAT
15626
    { "HAVE_FUTIMESAT", NULL },
15627
#endif
15628
15629
#ifdef HAVE_LINKAT
15630
    { "HAVE_LINKAT", probe_linkat },
15631
#endif
15632
15633
#ifdef HAVE_LCHFLAGS
15634
    { "HAVE_LCHFLAGS", NULL },
15635
#endif
15636
15637
#ifdef HAVE_LCHMOD
15638
    { "HAVE_LCHMOD", NULL },
15639
#endif
15640
15641
#ifdef HAVE_LCHOWN
15642
    { "HAVE_LCHOWN", NULL },
15643
#endif
15644
15645
#ifdef HAVE_LSTAT
15646
    { "HAVE_LSTAT", NULL },
15647
#endif
15648
15649
#ifdef HAVE_LUTIMES
15650
    { "HAVE_LUTIMES", NULL },
15651
#endif
15652
15653
#ifdef HAVE_MEMFD_CREATE
15654
    { "HAVE_MEMFD_CREATE", NULL },
15655
#endif
15656
15657
#ifdef HAVE_MKDIRAT
15658
    { "HAVE_MKDIRAT", probe_mkdirat },
15659
#endif
15660
15661
#ifdef HAVE_MKFIFOAT
15662
    { "HAVE_MKFIFOAT", NULL },
15663
#endif
15664
15665
#ifdef HAVE_MKNODAT
15666
    { "HAVE_MKNODAT", NULL },
15667
#endif
15668
15669
#ifdef HAVE_OPENAT
15670
    { "HAVE_OPENAT", probe_openat },
15671
#endif
15672
15673
#ifdef HAVE_READLINKAT
15674
    { "HAVE_READLINKAT", probe_readlinkat },
15675
#endif
15676
15677
#ifdef HAVE_RENAMEAT
15678
    { "HAVE_RENAMEAT", probe_renameat },
15679
#endif
15680
15681
#ifdef HAVE_SYMLINKAT
15682
    { "HAVE_SYMLINKAT", probe_symlinkat },
15683
#endif
15684
15685
#ifdef HAVE_UNLINKAT
15686
    { "HAVE_UNLINKAT", probe_unlinkat },
15687
#endif
15688
15689
#ifdef HAVE_UTIMENSAT
15690
    { "HAVE_UTIMENSAT", probe_utimensat },
15691
#endif
15692
15693
#ifdef MS_WINDOWS
15694
    { "MS_WINDOWS", NULL },
15695
#endif
15696
15697
    { NULL, NULL }
15698
};
15699
15700
15701
static int
15702
posixmodule_exec(PyObject *m)
15703
278
{
15704
278
    _posixstate *state = get_posix_state(m);
15705
15706
278
#if defined(HAVE_PWRITEV)
15707
278
    if (HAVE_PWRITEV_RUNTIME) {} else {
Line
Count
Source
177
278
#  define HAVE_PWRITEV_RUNTIME 1
  Branch (177:32): [Folded - Ignored]
15708
0
        PyObject* dct = PyModule_GetDict(m);
15709
15710
0
        if (dct == NULL) {
  Branch (15710:13): [True: 0, False: 0]
15711
0
            return -1;
15712
0
        }
15713
15714
0
        if (PyDict_DelItemString(dct, "pwritev") == -1) {
  Branch (15714:13): [True: 0, False: 0]
15715
0
            PyErr_Clear();
15716
0
        }
15717
0
        if (PyDict_DelItemString(dct, "preadv") == -1) {
  Branch (15717:13): [True: 0, False: 0]
15718
0
            PyErr_Clear();
15719
0
        }
15720
0
    }
15721
278
#endif
15722
15723
    /* Initialize environ dictionary */
15724
278
    PyObject *v = convertenviron();
15725
278
    Py_XINCREF(v);
Line
Count
Source
603
278
#  define Py_XINCREF(op) Py_XINCREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15726
278
    if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
  Branch (15726:9): [True: 0, False: 278]
  Branch (15726:22): [True: 0, False: 278]
15727
0
        return -1;
15728
278
    Py_DECREF(v);
Line
Count
Source
548
278
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15729
15730
278
    if (all_ins(m))
  Branch (15730:9): [True: 0, False: 278]
15731
0
        return -1;
15732
15733
278
    if (setup_confname_tables(m))
  Branch (15733:9): [True: 0, False: 278]
15734
0
        return -1;
15735
15736
278
    Py_INCREF(PyExc_OSError);
Line
Count
Source
512
278
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15737
278
    PyModule_AddObject(m, "error", PyExc_OSError);
15738
15739
278
#if defined(HAVE_WAITID) && !defined(__APPLE__)
15740
278
    waitid_result_desc.name = MODNAME ".waitid_result";
Line
Count
Source
492
278
#  define MODNAME "posix"
15741
278
    PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
15742
278
    if (WaitidResultType == NULL) {
  Branch (15742:9): [True: 0, False: 278]
15743
0
        return -1;
15744
0
    }
15745
278
    Py_INCREF(WaitidResultType);
Line
Count
Source
512
278
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15746
278
    PyModule_AddObject(m, "waitid_result", WaitidResultType);
15747
278
    state->WaitidResultType = WaitidResultType;
15748
278
#endif
15749
15750
278
    stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
15751
278
    stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
15752
278
    stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
15753
278
    stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
15754
278
    PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
15755
278
    if (StatResultType == NULL) {
  Branch (15755:9): [True: 0, False: 278]
15756
0
        return -1;
15757
0
    }
15758
278
    Py_INCREF(StatResultType);
Line
Count
Source
512
278
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15759
278
    PyModule_AddObject(m, "stat_result", StatResultType);
15760
278
    state->StatResultType = StatResultType;
15761
278
    structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
15762
278
    ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
15763
15764
278
    statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
15765
278
    PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
15766
278
    if (StatVFSResultType == NULL) {
  Branch (15766:9): [True: 0, False: 278]
15767
0
        return -1;
15768
0
    }
15769
278
    Py_INCREF(StatVFSResultType);
Line
Count
Source
512
278
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15770
278
    PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
15771
278
    state->StatVFSResultType = StatVFSResultType;
15772
278
#ifdef NEED_TICKS_PER_SECOND
15773
278
#  if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
15774
278
    ticks_per_second = sysconf(_SC_CLK_TCK);
15775
#  elif defined(HZ)
15776
    ticks_per_second = HZ;
15777
#  else
15778
    ticks_per_second = 60; /* magic fallback value; may be bogus */
15779
#  endif
15780
278
#endif
15781
15782
278
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
15783
278
    sched_param_desc.name = MODNAME ".sched_param";
Line
Count
Source
492
278
#  define MODNAME "posix"
15784
278
    PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
15785
278
    if (SchedParamType == NULL) {
  Branch (15785:9): [True: 0, False: 278]
15786
0
        return -1;
15787
0
    }
15788
278
    Py_INCREF(SchedParamType);
Line
Count
Source
512
278
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15789
278
    PyModule_AddObject(m, "sched_param", SchedParamType);
15790
278
    state->SchedParamType = SchedParamType;
15791
278
    ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
15792
278
#endif
15793
15794
    /* initialize TerminalSize_info */
15795
278
    PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
15796
278
    if (TerminalSizeType == NULL) {
  Branch (15796:9): [True: 0, False: 278]
15797
0
        return -1;
15798
0
    }
15799
278
    Py_INCREF(TerminalSizeType);
Line
Count
Source
512
278
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15800
278
    PyModule_AddObject(m, "terminal_size", TerminalSizeType);
15801
278
    state->TerminalSizeType = TerminalSizeType;
15802
15803
    /* initialize scandir types */
15804
278
    PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
15805
278
    if (ScandirIteratorType == NULL) {
  Branch (15805:9): [True: 0, False: 278]
15806
0
        return -1;
15807
0
    }
15808
278
    state->ScandirIteratorType = ScandirIteratorType;
15809
15810
278
    PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
15811
278
    if (DirEntryType == NULL) {
  Branch (15811:9): [True: 0, False: 278]
15812
0
        return -1;
15813
0
    }
15814
278
    Py_INCREF(DirEntryType);
Line
Count
Source
512
278
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15815
278
    PyModule_AddObject(m, "DirEntry", DirEntryType);
15816
278
    state->DirEntryType = DirEntryType;
15817
15818
278
    times_result_desc.name = MODNAME ".times_result";
Line
Count
Source
492
278
#  define MODNAME "posix"
15819
278
    PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
15820
278
    if (TimesResultType == NULL) {
  Branch (15820:9): [True: 0, False: 278]
15821
0
        return -1;
15822
0
    }
15823
278
    Py_INCREF(TimesResultType);
Line
Count
Source
512
278
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15824
278
    PyModule_AddObject(m, "times_result", TimesResultType);
15825
278
    state->TimesResultType = TimesResultType;
15826
15827
278
    PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
15828
278
    if (UnameResultType == NULL) {
  Branch (15828:9): [True: 0, False: 278]
15829
0
        return -1;
15830
0
    }
15831
278
    Py_INCREF(UnameResultType);
Line
Count
Source
512
278
#  define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
Line
Count
Source
109
278
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
278
#  define _Py_CAST(type, expr) ((type)(expr))
15832
278
    PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
15833
278
    state->UnameResultType = (PyObject *)UnameResultType;
15834
15835
278
    if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
  Branch (15835:9): [True: 0, False: 278]
15836
0
        return -1;
15837
278
#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
15838
278
    state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
15839
278
    if (state->struct_rusage == NULL)
  Branch (15839:9): [True: 0, False: 278]
15840
0
        return -1;
15841
278
#endif
15842
278
    state->st_mode = PyUnicode_InternFromString("st_mode");
15843
278
    if (state->st_mode == NULL)
  Branch (15843:9): [True: 0, False: 278]
15844
0
        return -1;
15845
15846
    /* suppress "function not used" warnings */
15847
278
    {
15848
278
    int ignored;
15849
278
    fd_specified("", -1);
15850
278
    follow_symlinks_specified("", 1);
15851
278
    dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
Line
Count
Source
904
278
#define DEFAULT_DIR_FD (int)AT_FDCWD
15852
278
    dir_fd_converter(Py_None, &ignored);
Line
Count
Source
654
278
#define Py_None (&_Py_NoneStruct)
15853
278
    dir_fd_unavailable(Py_None, &ignored);
Line
Count
Source
654
278
#define Py_None (&_Py_NoneStruct)
15854
278
    }
15855
15856
    /*
15857
     * provide list of locally available functions
15858
     * so os.py can populate support_* lists
15859
     */
15860
278
    PyObject *list = PyList_New(0);
15861
278
    if (!list) {
  Branch (15861:9): [True: 0, False: 278]
15862
0
        return -1;
15863
0
    }
15864
8.61k
    for (const struct have_function *trace = have_functions; trace->label; trace++) {
  Branch (15864:62): [True: 8.34k, False: 278]
15865
8.34k
        PyObject *unicode;
15866
8.34k
        if (trace->probe && !trace->probe()) continue;
  Branch (15866:13): [True: 3.89k, False: 4.44k]
  Branch (15866:29): [True: 0, False: 3.89k]
15867
8.34k
        unicode = PyUnicode_DecodeASCII(trace->label, strlen(trace->label), NULL);
15868
8.34k
        if (!unicode)
  Branch (15868:13): [True: 0, False: 8.34k]
15869
0
            return -1;
15870
8.34k
        if (PyList_Append(list, unicode))
  Branch (15870:13): [True: 0, False: 8.34k]
15871
0
            return -1;
15872
8.34k
        Py_DECREF(unicode);
Line
Count
Source
548
8.34k
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
Line
Count
Source
109
8.34k
#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op))
Line
Count
Source
71
8.34k
#  define _Py_CAST(type, expr) ((type)(expr))
15873
8.34k
    }
15874
15875
278
    PyModule_AddObject(m, "_have_functions", list);
15876
15877
278
    return 0;
15878
278
}
15879
15880
15881
static PyModuleDef_Slot posixmodile_slots[] = {
15882
    {Py_mod_exec, posixmodule_exec},
15883
    {0, NULL}
15884
};
15885
15886
static struct PyModuleDef posixmodule = {
15887
    PyModuleDef_HEAD_INIT,
15888
    .m_name = MODNAME,
15889
    .m_doc = posix__doc__,
15890
    .m_size = sizeof(_posixstate),
15891
    .m_methods = posix_methods,
15892
    .m_slots = posixmodile_slots,
15893
    .m_traverse = _posix_traverse,
15894
    .m_clear = _posix_clear,
15895
    .m_free = _posix_free,
15896
};
15897
15898
PyMODINIT_FUNC
15899
INITFUNC(void)
15900
278
{
15901
278
    return PyModuleDef_Init(&posixmodule);
15902
278
}
15903
15904
#ifdef __cplusplus
15905
}
15906
#endif